From 63b69f4e8a3acf4f86ccec4bec9e9067a983d8b4 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 12:23:14 -0500 Subject: [PATCH 01/49] alpha sort the includes in group2 --- groups/bsl/bsls/bsls_alignedbuffer.t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp index b055046682..4102a82757 100644 --- a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp +++ b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp @@ -2,8 +2,8 @@ #include -#include #include +#include #include #include From bc00c8c210b913fda9e5bafcb98f437eb243b42f Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 12:23:58 -0500 Subject: [PATCH 02/49] alpha sort includes --- groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index b2291ace9a..6413f9c530 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -4,14 +4,14 @@ #include // for testing only -#include // for testing only #include // for testing only #include // for testing only #include // for testing only +#include // for testing only #include // for testing only -#include // for testing only #include // for testing only #include // for testing only +#include // for testing only #include // for testing only #include From 2195a8536e85e845e94e17646a96c500fe5dd7ad Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 12:25:36 -0500 Subject: [PATCH 03/49] alpha sort includes --- groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp index 54faf834b2..f77bf66ddc 100644 --- a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp @@ -1,14 +1,13 @@ // bslalg_scalardestructionprimitives.t.cpp -*-C++-*- #include - #include // for testing only -#include // for testing only -#include // for testing only #include // for testing only #include // for testing only #include // for testing only +#include // for testing only +#include // for testing only #include // for testing only #include // for testing only #include // for testing only From 99736586af758efded5c159c718ed44ec7278cec Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 12:26:38 -0500 Subject: [PATCH 04/49] alpha sort includes --- groups/bsl/bslalg/bslalg_rangecompare.t.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp index ec35145961..69d71485c5 100644 --- a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp +++ b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp @@ -2,15 +2,13 @@ #include -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only - #include #include #include - +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only #include #include From e25dc057eb48403795305132554cfeaf1672d073 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 12:28:02 -0500 Subject: [PATCH 05/49] alpha sort includes --- groups/bsl/bslstl/bslstl_vector.t.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_vector.t.cpp b/groups/bsl/bslstl/bslstl_vector.t.cpp index 626f1e3d2e..e0feea9644 100644 --- a/groups/bsl/bslstl/bslstl_vector.t.cpp +++ b/groups/bsl/bslstl/bslstl_vector.t.cpp @@ -1,10 +1,9 @@ // bslstl_vector.t.cpp -*-C++-*- #include - #include -#include #include +#include #include #include @@ -13,13 +12,13 @@ #include // for testing only #include // for testing only #include // for testing only -#include #include #include #include +#include #include -#include #include // for testing only +#include #include #include From e95491aa2e96d99e380e44b8e9ac2cac3ebfdd25 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 12:28:40 -0500 Subject: [PATCH 06/49] alpha sort includes --- groups/bsl/bslstl/bslstl_string.t.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_string.t.cpp b/groups/bsl/bslstl/bslstl_string.t.cpp index 655d02bd07..ace74a84f0 100644 --- a/groups/bsl/bslstl/bslstl_string.t.cpp +++ b/groups/bsl/bslstl/bslstl_string.t.cpp @@ -1,7 +1,6 @@ // bslstl_string.t.cpp -*-C++-*- #include - #include #include @@ -12,12 +11,12 @@ #include // for testing only #include // for testing only #include // for testing only -#include -#include // for testing only -#include -#include #include #include +#include +#include +#include +#include // for testing only #include #include From 1191eda1fc208d33b4bf2737178ac9d70711411d Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 12:29:15 -0500 Subject: [PATCH 07/49] alpha sort includes --- groups/bsl/bslstl/bslstl_pair.t.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_pair.t.cpp b/groups/bsl/bslstl/bslstl_pair.t.cpp index b60b01b438..3f71ee1c71 100644 --- a/groups/bsl/bslstl/bslstl_pair.t.cpp +++ b/groups/bsl/bslstl/bslstl_pair.t.cpp @@ -2,17 +2,16 @@ #include -#include -#include -#include -#include -#include #include #include #include #include - +#include +#include +#include #include +#include +#include #include From c742ec28f68be42b9f9d47fd9f6d3cb505b5306a Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 14:45:00 -0500 Subject: [PATCH 08/49] fix BREATHING TEST 'Testing:' label --- groups/bsl/bsls/bsls_ident.t.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/groups/bsl/bsls/bsls_ident.t.cpp b/groups/bsl/bsls/bsls_ident.t.cpp index 9747e86e41..e86c4636fc 100644 --- a/groups/bsl/bsls/bsls_ident.t.cpp +++ b/groups/bsl/bsls/bsls_ident.t.cpp @@ -16,7 +16,7 @@ // This component does not have any easy way to do runtime checks. // //----------------------------------------------------------------------------- -// [ 1] Breathing Test (nothing) +// [ 1] BREATHING TEST //----------------------------------------------------------------------------- //========================================================================== @@ -146,11 +146,13 @@ int main(int argc, char *argv[]) case 1: { // -------------------------------------------------------------------- // BREATHING TEST - // - // Concerns: That there is no real runtime test for this component. + // Concerns: That there is no real runtime test for this component. // // Plan: // Do nothing. + // + // Testing: + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) std::cout << "\nBREATHING TEST" From eaf87af3558ac9c5ea28023d33e3db02685ea4a0 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 14:54:41 -0500 Subject: [PATCH 09/49] correct the 'Testing:' label to match the Test Plan Checklist --- groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index 6413f9c530..3597beef06 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -740,7 +740,7 @@ int main(int argc, char *argv[]) //: they are destroyed as expected. (C-1) // // Testing: - // void destroy(T *b, T *e, *a); + // void destroy(T *dstB, T *dstE); // -------------------------------------------------------------------- if (verbose) printf("\nTesting 'destroy'\n"); From 441e726c0c61e4efebfd1ef7220d9b4c2d2125d9 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 14:56:17 -0500 Subject: [PATCH 10/49] alter 'Testing:' label targets to match case of Test Plan Checklist --- groups/bsl/bsls/bsls_alignedbuffer.t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp index 4102a82757..93eb416dd7 100644 --- a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp +++ b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp @@ -225,7 +225,7 @@ int main(int argc, char *argv[]) // - sizeof(Buff) - SIZE < ALIGNMENT // // Testing: - // Class Invariants + // CLASS INVARIANTS // -------------------------------------------------------------------- if (verbose) printf("\nTESTING CLASS INVARIANTS" From 35b7e252d37b31ac78a55c5431a79eec4b7fc9de Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 14:57:44 -0500 Subject: [PATCH 11/49] In case 1, alter 'Testing:' label target to match the Test Plan Checklist --- groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp index f77bf66ddc..0bf0fedba0 100644 --- a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp @@ -772,7 +772,7 @@ int main(int argc, char *argv[]) //: them. Make sure all memory is deallocated. // // Testing: - // This test exercises the component but tests nothing. + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" From 63f0448e50c603a9fdaa499b4da7e293c3996e58 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 15:07:53 -0500 Subject: [PATCH 12/49] make the 'Testing:' label and Test Plan Checklist match. --- groups/bsl/bslalg/bslalg_rangecompare.t.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp index 69d71485c5..0805e7a9bc 100644 --- a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp +++ b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp @@ -45,7 +45,10 @@ using namespace std; // overloads, we wrap the range pointers into an iterator type that is *not* // convertible to the pointer. //----------------------------------------------------------------------------- +// [ 3] bool equal(start1, end1, start2); +// [ 3] bool equal(start1, end1, start2, end2); // [ 3] bool equal(start1, end1, length1, start2, end2, length2); +// [ 4] bool lexicographical(start1, end1, start2, end2); // [ 4] bool lexicographical(start1, end1, length1, start2, end2, length2); //----------------------------------------------------------------------------- // [ 1] BREATHING TEST @@ -2362,8 +2365,7 @@ int main(int argc, char *argv[]) // the first invalid value of the 'spec'. // // Testing: - // int ggg(TYPE *array, const char *spec, int verboseFlag = 1); - // TYPE& gg(TYPE *array, const char *spec); + // TEST APPARATUS // -------------------------------------------------------------------- if (verbose) printf("\nTESTING PRIMITIVE GENERATOR FUNCTIONS" @@ -2393,7 +2395,7 @@ int main(int argc, char *argv[]) // Exercise basic usage of this component. // // Testing: - // This test exercises basic usage but *tests* nothing. + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" @@ -2495,6 +2497,7 @@ int main(int argc, char *argv[]) // can be used. Display the resulting times. // // Testing: + // PERFORMANCE TEST // -------------------------------------------------------------------- if (verbose) printf("\nPERFORMANCE TEST" From b687eda99de94fe0a68a4294c1935ebcd7df217e Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 21:30:08 -0500 Subject: [PATCH 13/49] Fixed a number of 'Testing:' labels so they match the Test Plan checklist exactly --- groups/bsl/bslstl/bslstl_string.t.cpp | 239 ++++++++++++++------------ 1 file changed, 127 insertions(+), 112 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_string.t.cpp b/groups/bsl/bslstl/bslstl_string.t.cpp index ace74a84f0..f62e2b458c 100644 --- a/groups/bsl/bslstl/bslstl_string.t.cpp +++ b/groups/bsl/bslstl/bslstl_string.t.cpp @@ -107,8 +107,7 @@ using namespace std; // [12] string(const C *s, n, a = A()); // [12] string(const C *s, a = A()); // [12] string(n, C c, a = A()); -// [12] template -// string(InputIter first, InputIter last, a = A()); +// [12] template string(InputIter,InputIter,a = A()); // [ 7] string(const string& orig, a = A()); // [ 2] ~string(); // @@ -127,24 +126,22 @@ using namespace std; // [14] void resize(size_type n, C c); // [14] void reserve(size_type n); // [ 2] void clear(); -// [15] reference operator[](size_type pos); -// [15] reference at(size_type pos); -// [15] reference front(); -// [15] reference back(); +// [15] T& operator[](size_type pos); +// [15] T& at(size_type pos); +// [15] T& front(); +// [15] T& back(); // [13] void assign(const string& str); // [13] void assign(const string& str, pos, n); // [13] void assign(const C *s, size_type n); // [13] void assign(const C *s); // [13] void assign(size_type n, C c); -// [13] template -// void assign(InputIter first, InputIter last); +// [13] template void assign(IIter,IIter); // [17] string& append(const string& str); // [17] string& append(const string& str, pos, n); // [17] string& append(const C *s, size_type n); // [17] string& append(const C *s); // [17] string& append(size_type n, C c); -// [17] template -// string& append(InputIter first, InputIter last); +// [17] template string& append(IIter,IIter); // [ 2] void push_back(C c); // [18] string& insert(size_type pos1, const string& str); // [18] string& insert(size_type pos1, const string& str, pos2, n); @@ -153,8 +150,7 @@ using namespace std; // [18] string& insert(size_type pos, size_type n, C c); // [18] iterator insert(const_iterator p, C c); // [18] iterator insert(const_iterator p, size_type n, C c); -// [18] template -// iterator insert(const_iterator p, InputIter first, InputIter last); +// [18] template iterator insert(citer,IIter,IIter); // [19] void pop_back(); // [19] iterator erase(size_type pos = 0, size_type n = npos); // [19] iterator erase(const_iterator p); @@ -164,27 +160,26 @@ using namespace std; // [20] string& replace(pos1, n1, const C *s, n2); // [20] string& replace(pos1, n1, const C *s); // [20] string& replace(pos1, n1, size_type n2, C c); -// [20] replace(const_iterator first, const_iterator last, const string& str); -// [20] replace(const_iterator first, const_iterator last, const C *s, n2); -// [20] replace(const_iterator first, const_iterator last, const C *s); -// [20] replace(const_iterator first, const_iterator last, size_type n2, C c); -// [20] template -// replace(const_iterator p, const_iterator q, InputIter f, InputIter l); +// [20] replace(const_iterator p, const_iterator q, const string& str); +// [20] replace(const_iterator p, const_iterator q, const C *s, n2); +// [20] replace(const_iterator p, const_iterator q, const C *s); +// [20] replace(const_iterator p, const_iterator q, size_type n2, C c); +// [20] template replace(citer,citer,IIter,IIter); // [21] void swap(string&); // // ACCESSORS: // [ 4] const_reference operator[](size_type pos) const; // [ 4] const_reference at(size_type pos) const; -// [15] const_reference front() const; -// [15] const_reference back() const; +// [15] const T& front() const; +// [15] const T& back() const; // [ 4] size_type size() const; // [14] size_type max_size() const; // [14] size_type capacity() const; // [14] bool empty() const; -// [16] const_iterator begin(); -// [16] const_iterator end(); -// [16] const_reverse_iterator rbegin(); -// [16] const_reverse_iterator rend(); +// [16] const_iterator begin() const; +// [16] const_iterator end() const; +// [16] const_reverse_iterator rbegin() const; +// [16] const_reverse_iterator rend() const; // [ ] const C *c_str() const; // [ ] const C *data() const; // [22] size_type find(const string& str, pos = 0) const; @@ -239,6 +234,7 @@ using namespace std; // [24] bool operator>=(const string&, const string&); // [24] bool operator>=(const C *, const string&); // [24] bool operator>=(const string&, const C *); +// [21] void swap(string&); // [21] void swap(string&, string&); // [ 5] basic_ostream& operator<<(basic_ostream& stream, // const string& str); @@ -248,6 +244,11 @@ using namespace std; // [ 1] BREATHING TEST // [11] ALLOCATOR-RELATED CONCERNS // [25] CONCERN: 'std::length_error' is used properly +// [26] npos +// [26] operator native_stl::string() const; +// [26] string(const native_stl::basic_string&); +// [27] DRQS 16870796: SEGFAULT IN FIND +// [28] SHORT STRING OPTIMIZATION // // TEST APPARATUS: GENERATOR FUNCTIONS // [ 3] int ggg(string *object, const char *spec, int vF = 1); @@ -1295,16 +1296,15 @@ void TestDriver::testCase26() // -------------------------------------------------------------------- // TESTING CONVERSIONS WITH NATIVE STRINGS // - // Testing: - // CONCERNS: - // - A bsl::basic_string is implicitly convertible to a - // native_std::basic_string with the same CHAR_TYPE and - // CHAR_TRAITS. - // - A native_std::basic_string is explicitly convertible to a - // bsl::basic_string with the same CHAR_TYPE and - // CHAR_TRAITS. - // - A bsl::basic_string and a native_std::basic_string with the - // same template parameters will have the same npos value. + // CONCERNS: + // - A bsl::basic_string is implicitly convertible to a + // native_std::basic_string with the same CHAR_TYPE and + // CHAR_TRAITS. + // - A native_std::basic_string is explicitly convertible to a + // bsl::basic_string with the same CHAR_TYPE and + // CHAR_TRAITS. + // - A bsl::basic_string and a native_std::basic_string with the + // same template parameters will have the same npos value. // // Plan: // For a variety of strings of different sizes and different values, test @@ -1315,10 +1315,8 @@ void TestDriver::testCase26() // // Testing: // npos - // operator native_stl::basic_string() const; - // basic_string(const native_stl::basic_string&); + // operator native_stl::string() const; + // string(const native_stl::basic_string&); // ------------------------------------------------------------------------ static const char *SPECS[] = { @@ -1473,7 +1471,7 @@ void TestDriver::testCase25() // in a value exceeding 'max_size()'. // // Testing: - // Proper use of 'std::length_error' + // CONCERN: 'std::length_error' is used properly // ------------------------------------------------------------------------ bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -2406,24 +2404,24 @@ void TestDriver::testCase24() // well. // // Testing: - // int compare(const string& str) const; - // int compare(pos1, n1, const string& str) const; - // int compare(pos1, n1, const string& str, pos2, n2) const; - // int compare(const C* s) const; - // int compare(pos1, n1, const C* s) const; - // int compare(pos1, n1, const C* s, n2) const; - // bool operator<(const string&, const string&); - // bool operator<(const C *, const string&); - // bool operator<(const string&, const C *); - // bool operator>(const string&, const string&); - // bool operator>(const C *, const string&); - // bool operator>(const string&, const C *); - // bool operator<=(const string&, const string&); - // bool operator<=(const C *, const string&); - // bool operator<=(const string&, const C *); - // bool operator>=(const string&, const string&); - // bool operator>=(const C *, const string&); - // bool operator>=(const string&, const C *); + // int compare(const string& str) const; + // int compare(pos1, n1, const string& str) const; + // int compare(pos1, n1, const string& str, pos2, n2) const; + // int compare(const C* s) const; + // int compare(pos1, n1, const C* s) const; + // int compare(pos1, n1, const C* s, n2) const; + // bool operator<(const string&, const string&); + // bool operator<(const C *, const string&); + // bool operator<(const string&, const C *); + // bool operator>(const string&, const string&); + // bool operator>(const C *, const string&); + // bool operator>(const string&, const C *); + // bool operator<=(const string&, const string&); + // bool operator<=(const C *, const string&); + // bool operator<=(const string&, const C *); + // bool operator>=(const string&, const string&); + // bool operator>=(const C *, const string&); + // bool operator>=(const string&, const C *); // ------------------------------------------------------------------------ static const char *SPECS[] = { @@ -2609,17 +2607,15 @@ void TestDriver::testCase24Negative() // 'compare' method. // // Testing: - // int compare(const C* s) const; - // int compare(pos1, n1, const C* s) const; - // int compare(pos1, n1, const C* s, n2) const; - // bool operator<(const C *s, const string& str); - // bool operator<(const string& str, const C *s); - // bool operator>(const C *s, const string& str); - // bool operator>(const string& str, const C *s); - // bool operator<=(const C *s, const string& str); - // bool operator<=(const string& str, const C *s); - // bool operator>=(const C *s, const string& str); - // bool operator>=(const string& str, const C *s); + // int compare(const C* s) const; + // int compare(pos1, n1, const C* s) const; + // int compare(pos1, n1, const C* s, n2) const; + // bool operator<(const C *, const string&) + // bool operator>(const C *, const string&); + // bool operator>(const string&, const C *); + // bool operator<=(const string&, const string&); + // bool operator<=(const C *, const string&); + // bool operator<=(const string&, const C *); // ----------------------------------------------------------------------- bsls::AssertFailureHandlerGuard guard(&bsls::AssertTest::failTestDriver); @@ -8616,8 +8612,8 @@ void TestDriver::testCase13() // be tested more completely in test case 25. // // Testing: - // void assign(const string& str); - // void assign(const string& str, pos, n); + // void assign(const string& str); + // void assign(const string& str, pos, n); // void assign(const C *s, size_type n); // void assign(const C *s); // void assign(size_type n, C c); @@ -8798,8 +8794,7 @@ void TestDriver::testCase13Range(const CONTAINER&) // completely in test case 17. // // Testing: - // template - // assign(InputIter first, InputIter last, const A& a = A()); + // template void assign(IIter,IIter); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -13865,6 +13860,9 @@ int main(int argc, char *argv[]) // - It should work with the NULL-terminator different from '\0' to // make sure that the implementation always uses char_type() default // constructor to terminate the string rather than a null literal. + // + // Testing: + // SHORT STRING OPTIMIZATION // -------------------------------------------------------------------- if (verbose) printf("\nTesting the short string optimization" "\n=====================================\n"); @@ -13889,14 +13887,15 @@ int main(int argc, char *argv[]) case 27: { // -------------------------------------------------------------------- // REPRODUCING KNOWN BUG CAUSING SEGFAULT IN FIND - // + // This is a problem with the native library, being pursued in DRQS + // 16870796. This test will do nothing unless run in verbose mode. + // // Concerns: // That a known bug in string::find on Sun cc is reproduced in this // test suite. // // Testing: - // This is a problem with the native library, being pursued in DRQS - // 16870796. This test will do nothing unless run in verbose mode. + // DRQS 16870796: SEGFAULT IN FIND // -------------------------------------------------------------------- if (verbose) printf("\nReproducing known segfault in string::find" @@ -13921,16 +13920,20 @@ int main(int argc, char *argv[]) // -------------------------------------------------------------------- // TESTING CONVERSIONS WITH NATIVE STRINGS // + // CONCERNS: + // - A bsl::basic_string is implicitly convertible to a + // native_std::basic_string with the same CHAR_TYPE and + // CHAR_TRAITS. + // - A native_std::basic_string is implicitly convertible to a + // bsl::basic_string with the same CHAR_TYPE and + // CHAR_TRAITS. + // - A bsl::basic_string and a native_std::basic_string with the + // same template parameters will have the same npos value. + // // Testing: - // CONCERNS: - // - A bsl::basic_string is implicitly convertible to a - // native_std::basic_string with the same CHAR_TYPE and - // CHAR_TRAITS. - // - A native_std::basic_string is implicitly convertible to a - // bsl::basic_string with the same CHAR_TYPE and - // CHAR_TRAITS. - // - A bsl::basic_string and a native_std::basic_string with the - // same template parameters will have the same npos value. + // npos + // operator native_stl::string() const; + // string(const native_stl::basic_string&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting conversions to/from native string" @@ -13972,10 +13975,10 @@ int main(int argc, char *argv[]) // int compare(const C* s) const; // int compare(pos1, n1, const C* s) const; // int compare(pos1, n1, const C* s, n2) const; - // bool operator<(const string&, const string&); - // bool operator>(const string&, const string&); - // bool operator<=(const string&, const string&); - // bool operator>=(const string&, const string&); + // bool operator<(const string&, const string&); + // bool operator>(const string&, const string&); + // bool operator<=(const string&, const string&); + // bool operator>=(const string&, const string&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting comparisons" @@ -14087,7 +14090,7 @@ int main(int argc, char *argv[]) // // Testing: // void swap(string&); - // void swap(string& lhs, string& rhs); + // void swap(string&, string&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting 'swap'" @@ -14114,8 +14117,7 @@ int main(int argc, char *argv[]) // replace(const_iterator p, const_iterator q, const C *s, n2); // replace(const_iterator p, const_iterator q, const C *s); // replace(const_iterator p, const_iterator q, size_type n2, C c); - // template - // replace(const_iterator p, const_iterator q, InputIter f, l); + // template replace(citer,citer,IIter,IIter); // -------------------------------------------------------------------- if (verbose) printf("\nTesting 'replace' with value" @@ -14163,10 +14165,10 @@ int main(int argc, char *argv[]) // TESTING ERASE // // Testing: - // iterator erase(size_type pos, n); - // iterator erase(const_iterator position); - // iterator erase(const_iterator first, iterator last); - // void pop_back(); + // void pop_back(); + // iterator erase(size_type pos = 0, size_type n = npos); + // iterator erase(const_iterator p); + // iterator erase(const_iterator first, iterator last); // -------------------------------------------------------------------- if (verbose) printf("\nTesting 'erase' and 'pop_back'" @@ -14195,11 +14197,14 @@ int main(int argc, char *argv[]) // TESTING INSERTION // // Testing: - // iterator insert(const_iterator position, const T& value); - // iterator insert(const_iterator pos, size_type n, const T& val); - // template - // iterator - // insert(const_iterator pos, InputIter first, InputIter last); + // string& insert(size_type pos1, const string& str); + // string& insert(size_type pos1, const string& str, pos2, n); + // string& insert(size_type pos, const C *s, n2); + // string& insert(size_type pos, const C *s); + // string& insert(size_type pos, size_type n, C c); + // iterator insert(const_iterator p, C c); + // iterator insert(const_iterator p, size_type n, C c); + // template iterator insert(citer,IIter,IIter); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Value Insertion" @@ -14247,8 +14252,12 @@ int main(int argc, char *argv[]) // TESTING APPEND // // Testing: - // template - // void append(InputIter first, InputIter last); + // string& append(const string& str); + // string& append(const string& str, pos, n); + // string& append(const C *s, size_type n); + // string& append(const C *s); + // string& append(size_type n, C c); + // template string& append(IIter,IIter); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Value Append" @@ -14321,8 +14330,8 @@ int main(int argc, char *argv[]) // TESTING ELEMENT ACCESS // // Testing: - // T& operator[](size_type position); - // T& at(size_type n); + // T& operator[](size_type pos); + // T& at(size_type pos); // T& front(); // T& back(); // const T& front() const; @@ -14355,8 +14364,9 @@ int main(int argc, char *argv[]) // TESTING CAPACITY // // Testing: - // void reserve(size_type n); - // void resize(size_type n, T val); + // void resize(size_type n); + // void resize(size_type n, C c); + // void reserve(size_type n); // size_type max_size() const; // size_type capacity() const; // bool empty() const; @@ -14377,9 +14387,12 @@ int main(int argc, char *argv[]) // TESTING ASSIGNMENT // // Testing: - // void assign(size_t n, const T& val); - // template - // void assign(InputIter first, InputIter last); + // void assign(const string& str); + // void assign(const string& str, pos, n); + // void assign(const C *s, size_type n); + // void assign(const C *s); + // void assign(size_type n, C c); + // template void assign(IIter,IIter); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Initial-Length Assignment" @@ -14427,9 +14440,11 @@ int main(int argc, char *argv[]) // TESTING CONSTRUCTORS // // Testing: - // string(size_type n, const T& val = T(), a = A()); - // template - // string(InputIter first, InputIter last, a = A()); + // string(const string& str, pos, n = npos, a = A()); + // string(const C *s, n, a = A()); + // string(const C *s, a = A()); + // string(n, C c, a = A()); + // template string(InputIter,InputIter,a = A()); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Initial-Length Constructor" From e9d5e5ed89b5b0cda4810f90be13cc1269442962 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 21:45:48 -0500 Subject: [PATCH 14/49] make CASE 4 'Testing:' label targets match Test Plan checklist --- groups/bsl/bslstl/bslstl_string.t.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_string.t.cpp b/groups/bsl/bslstl/bslstl_string.t.cpp index f62e2b458c..5ccae00642 100644 --- a/groups/bsl/bslstl/bslstl_string.t.cpp +++ b/groups/bsl/bslstl/bslstl_string.t.cpp @@ -14492,7 +14492,7 @@ int main(int argc, char *argv[]) // TESTING ALLOCATOR-RELATED CONCERNS // // Testing: - // Allocator TRAITS + // ALLOCATOR-RELATED CONCERNS // -------------------------------------------------------------------- if (verbose) printf("\nTesting Allocator concerns" @@ -14527,7 +14527,9 @@ int main(int argc, char *argv[]) // See that function for a list of concerns and a test plan. // // Testing: - // Obj& operator=(const Obj& rhs); + // operator=(const string& rhs); + // operator=(const C *s); + // operator=(c); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Assignment Operator" @@ -14564,7 +14566,8 @@ int main(int argc, char *argv[]) // that function for a list of concerns and a test plan. // // Testing: - // Obj g(const char *spec); + // string g(const char *spec); + // string g(size_t len, TYPE seed); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Generator Function g" @@ -14587,8 +14590,7 @@ int main(int argc, char *argv[]) // that function for a list of concerns and a test plan. // // Testing: - // string(const string& original); - // string(const string& original, alloc); + // string(const string& orig, a = A()); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Copy Constructors" @@ -14617,7 +14619,12 @@ int main(int argc, char *argv[]) // plan. // // Testing: - // operator==(const Obj&, const Obj&); + // bool operator==(const string&, const string&); + // bool operator==(const C *, const string&); + // bool operator==(const string&, const C *); + // bool operator!=(const string&, const string&); + // bool operator!=(const C *, const string&); + // bool operator!=(const string&, const C *); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Equality Operators" @@ -14667,8 +14674,9 @@ int main(int argc, char *argv[]) // for a list of concerns and a test plan. // // Testing: - // int size() const; - // const int& operator[](int index) const; + // const_reference operator[](size_type pos) const; + // const_reference at(size_type pos) const; + // size_type size() const; // -------------------------------------------------------------------- if (verbose) printf("\nTesting Basic Accessors" From 38faa4efb7138592dafc3e9e11943433a264fa7c Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 21:48:24 -0500 Subject: [PATCH 15/49] make CASE 3 'Testing:' label targets match the Test Plan checklist --- groups/bsl/bslstl/bslstl_string.t.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_string.t.cpp b/groups/bsl/bslstl/bslstl_string.t.cpp index 5ccae00642..d6f1132080 100644 --- a/groups/bsl/bslstl/bslstl_string.t.cpp +++ b/groups/bsl/bslstl/bslstl_string.t.cpp @@ -14697,8 +14697,8 @@ int main(int argc, char *argv[]) // function for a list of concerns and a test plan. // // Testing: - // void ggg(Obj *object, const char *spec); - // Obj& gg(Obj *object, const char *spec, ); + // int ggg(string *object, const char *spec, int vF = 1); + // string& gg(string *object, const char *spec); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Generator Functions" From 33d0cc6fb460c9a724c8ac40e4f419620cfffb10 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 21:54:54 -0500 Subject: [PATCH 16/49] make 'Testing:' target match Test Plan checklist exactly --- groups/bsl/bslstl/bslstl_string.t.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_string.t.cpp b/groups/bsl/bslstl/bslstl_string.t.cpp index d6f1132080..90f70025a6 100644 --- a/groups/bsl/bslstl/bslstl_string.t.cpp +++ b/groups/bsl/bslstl/bslstl_string.t.cpp @@ -249,6 +249,7 @@ using namespace std; // [26] string(const native_stl::basic_string&); // [27] DRQS 16870796: SEGFAULT IN FIND // [28] SHORT STRING OPTIMIZATION +// [-1] PERFORMANCE TEST // // TEST APPARATUS: GENERATOR FUNCTIONS // [ 3] int ggg(string *object, const char *spec, int vF = 1); @@ -14723,7 +14724,7 @@ int main(int argc, char *argv[]) // plan. // // Testing: - // void push_back(T const& v); + // void push_back(C c); // void clear(); // -------------------------------------------------------------------- @@ -14750,7 +14751,7 @@ int main(int argc, char *argv[]) // work as expected in normal operation. // // Testing: - // This "test" *exercises* basic functionality. + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" @@ -14875,8 +14876,7 @@ int main(int argc, char *argv[]) // access patterns, function call frequencies, etc. // // Testing: - // This "test" measures performance of basic operations, for - // performance regression. + // PERFORMANCE TEST // -------------------------------------------------------------------- if (verbose) printf("\nTesting Performance" From cfc8aa018a58d0be7b66041e63a1e85d902003ab Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 23:11:35 -0500 Subject: [PATCH 17/49] make all 'Testing:' label targets in testCaseNN functions also match the Test Plan checklist --- groups/bsl/bslstl/bslstl_string.t.cpp | 221 ++++++++++++-------------- 1 file changed, 105 insertions(+), 116 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_string.t.cpp b/groups/bsl/bslstl/bslstl_string.t.cpp index 90f70025a6..b18066274f 100644 --- a/groups/bsl/bslstl/bslstl_string.t.cpp +++ b/groups/bsl/bslstl/bslstl_string.t.cpp @@ -222,6 +222,8 @@ using namespace std; // [ 6] bool operator!=(const string&, const string&); // [ 6] bool operator!=(const C *, const string&); // [ 6] bool operator!=(const string&, const C *); +// [17] operator+(const string& lhs, const CHAR_TYPE *rhs); +// [17] operator+(const CHAR_TYPE *lhs, const string& rhs); // [24] bool operator<(const string&, const string&); // [24] bool operator<(const C *, const string&); // [24] bool operator<(const string&, const C *); @@ -5819,11 +5821,9 @@ void TestDriver::testCase18() // - element value at each index position { 0 .. length - 1 }. // // Testing: - // string& insert(size_type pos, size_type n, C c); // iterator insert(const_iterator p, size_type n, C c); + // string& insert(size_type pos, size_type n, C c); // iterator insert(const_iterator p, C c); - // // string& insert(size_type pos, const C *s, n2); - // // string& insert(size_type pos, const C *s); // ----------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -6910,12 +6910,11 @@ void TestDriver::testCase18Negative() // with invalid iterators and verify that it asserts. // // Testing: - // string& insert(size_type pos, const C *s); // string& insert(size_type pos, const C *s, n2); + // string& insert(size_type pos, const C *s); // iterator insert(const_iterator p, C c); // iterator insert(const_iterator p, size_type n, C c); - // template - // iterator insert(const_iterator p, InputIter first, InputIter last); + // template iterator insert(citer,IIter,IIter); // ----------------------------------------------------------------------- bsls::AssertFailureHandlerGuard guard(&bsls::AssertTest::failTestDriver); @@ -7022,7 +7021,6 @@ void TestDriver::testCase17() // // Testing: // string& append(size_type n, C c); - // // operator+=(c); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -7243,14 +7241,11 @@ void TestDriver::testCase17Range(const CONTAINER&) // - element value at each index position { 0 .. length - 1 }. // // Testing: - // string& append(const string& str); - // string& append(const string& str, pos, n); + // string& append(const string& str); + // string& append(const string& str, pos, n); // string& append(const C *s, size_type n); // string& append(const C *s); - // template - // append(InputIter first, InputIter last); - // // operator+=(const string& rhs); - // // operator+=(const C *s); + // template string& append(IIter,IIter); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -7869,7 +7864,7 @@ void TestDriver::testCase17Negative() // Testing: // string& append(const C *s, size_type n); // string& append(const C *s); - // template append(InputIter first, InputIter last); + // template string& append(IIter,IIter); // operator+=(const string& rhs); // operator+(const string& lhs, const CHAR_TYPE *rhs); // operator+(const CHAR_TYPE *lhs, const string& rhs); @@ -8094,8 +8089,8 @@ void TestDriver::testCase15() // 'std::out_of_range' when accessing the past-the-end element. // // Testing: - // T& operator[](size_type position); - // T& at(size_type n); + // T& operator[](size_type pos); + // T& at(size_type pos); // T& front(); // T& back(); // const T& front() const; @@ -8216,8 +8211,8 @@ void TestDriver::testCase15Negative() // index is out of range. // // Testing: - // T& operator[](size_type position); - // const T& operator[](size_type position) const; + // T& operator[](size_type pos); + // const T& operator[](size_type pos) const; // T& front(); // T& back(); // const T& front() const; @@ -8330,7 +8325,7 @@ void TestDriver::testCase14() // each test in the standard 'bslma' exception-testing macro block. // // Testing: - // void string::reserve(size_type n); + // void reserve(size_type n); // void resize(size_type n); // void resize(size_type n, C c); // size_type max_size() const; @@ -8995,8 +8990,7 @@ void TestDriver::testCase13Negative() // Testing: // void assign(const C *s, size_type n); // void assign(const C *s); - // template - // assign(InputIter first, InputIter last, const A& a = A()); + // template void assign(IIter,IIter); // -------------------------------------------------------------------- bsls::AssertFailureHandlerGuard guard(&bsls::AssertTest::failTestDriver); @@ -9065,11 +9059,10 @@ void TestDriver::testCase12() // expected, and that no allocation was performed. // // Testing: - // string(const string& str, pos, n = npos, a = A()); - // string(const C *s, n, a = A()); - // string(const C *s, a = A()); - // string(n, C c, a = A()); - // string(const string& original, a = A()); + // string(const string& str, pos, n = npos, a = A()); + // string(const C *s, n, a = A()); + // string(const C *s, a = A()); + // string(n, C c, a = A()); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -9651,8 +9644,7 @@ void TestDriver::testCase12Range(const CONTAINER&) // - element value at each index position { 0 .. length - 1 }. // // Testing: - // template - // string(InputIter first, InputIter last, a = A()); + // template string(InputIter,InputIter,a = A()); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -9851,10 +9843,9 @@ void TestDriver::testCase12Negative() // iterator range ('first > last') and verify that it asserts. // // Testing: - // string(const C *s, n, a = A()); - // string(const C *s, a = A()); - // template - // string(InputIter first, InputIter last, a = A()); + // string(const C *s, n, a = A()); + // string(const C *s, a = A()); + // template string(InputIter,InputIter,a = A()); // -------------------------------------------------------------------- bsls::AssertFailureHandlerGuard guard(&bsls::AssertTest::failTestDriver); @@ -9889,9 +9880,6 @@ void TestDriver::testCase11() // We verify that the 'string' class has the traits, and // that allocator is not used for creating empty strings. // - // Testing: - // TRAITS - // // TBD When a new string object Y is created from an old string object // X, then the standard states that Y should get its allocator by // copying X's allocator (23.1, Point 8). The STLport string @@ -9899,6 +9887,9 @@ void TestDriver::testCase11() // based allocators. To verify this behavior for non // bslma::Allocator, should test, copy constructor using one // and verify standard is followed. + // + // Testing: + // TRAITS // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -9974,9 +9965,9 @@ void TestDriver::testCase9() // With allocator, not moveable // // Testing: - // string& operator=(const string& rhs); - // string& operator=(const C *s); - // string& operator=(c); + // operator=(const string& rhs); + // operator=(const C *s); + // operator=(c); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -10291,7 +10282,7 @@ void TestDriver::testCase9Negative() // that it succeeds. // // Testing: - // string& operator=(const CHAR_TYPE *); + // operator=(const C *s); // -------------------------------------------------------------------- bsls::AssertFailureHandlerGuard guard(&bsls::AssertTest::failTestDriver); @@ -10463,7 +10454,7 @@ void TestDriver::testCase7() // 'bslma::TestAllocator' and varying its *allocation* *limit*. // // Testing: - // string(const string& original, a = A()); + // string(const string& orig, a = A()); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -10780,12 +10771,12 @@ void TestDriver::testCase6() // trait or not. // // Testing: - // operator==(const string&, const string&); - // operator==(const C *, const string&); - // operator==(const string&, const C *); - // operator!=(const string&, const string&); - // operator!=(const C *, const string&); - // operator!=(const string&, const C *); + // bool operator==(const string&, const string&); + // bool operator==(const C *, const string&); + // bool operator==(const string&, const C *); + // bool operator!=(const string&, const string&); + // bool operator!=(const C *, const string&); + // bool operator!=(const string&, const C *); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator1(veryVeryVerbose); @@ -10965,10 +10956,10 @@ void TestDriver::testCase6Negative() // C-string pointer parameters. // // Testing: - // operator==(const C *s, const string& str); - // operator==(const string& str, const C *s); - // operator!=(const C *s, const string& str); - // operator!=(const string& str, const C *s); + // bool operator==(const C *, const string&); + // bool operator==(const string&, const C *); + // bool operator!=(const C *, const string&); + // bool operator!=(const string&, const C *); // ----------------------------------------------------------------------- bsls::AssertFailureHandlerGuard guard(&bsls::AssertTest::failTestDriver); @@ -11051,10 +11042,9 @@ void TestDriver::testCase4() // Note - Using untested resize(int). // // Testing: - // reference operator[](size_type pos); // const_reference operator[](size_type pos) const; - // reference at(size_type pos); // const_reference at(size_type pos) const; + // size_type size() const; // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -11385,8 +11375,8 @@ void TestDriver::testCase3() // parser only; the primary manipulators are already assumed to work. // // Testing: - // string& gg(string *object, const char *spec); - // int ggg(string *object, const char *spec, int vF = 1); + // int ggg(string *object, const char *spec, int vF = 1); + // string& gg(string *object, const char *spec); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -11627,9 +11617,9 @@ void TestDriver::testCase2() // constants. // // Testing: - // string(const A& a = A()); - // ~string(); - // void push_back(const T&); + // string(a = A()); + // ~string(); + // void push_back(C c); // void clear(); // -------------------------------------------------------------------- @@ -12012,7 +12002,7 @@ void TestDriver::testCase1() // 11) Assign x4 = x4 (aliasing). { x1: x2: x3:AB x4:AB } // // Testing: - // This "test" *exercises* basic functionality. + // BREATHING TEST // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -12276,11 +12266,9 @@ void TestDriver::testCaseM1(const int NITER, // // Also note, that this is spaghetti code but we make no attempt at // shortening it with helper functions or macros, since we feel that - // - // Testing: // This "test" measures performance of basic operations, for performance // regression. - // + // // // RESULTS: Native SunProSTL on sundev13 as of Tue Jun 24 16:48:36 EDT 2008 // ------------------------------------------------------------------------ @@ -12455,8 +12443,9 @@ void TestDriver::testCaseM1(const int NITER, // M2 Substring: 2.23025s 6.25982s 8.490068s // // RESULTS: bslstl 1.11 on ibm1 as of Mon Jun 30 14:24:46 EDT 2008 - // -------------------------------------------------------------------- - // + // + // Testing: + // PERFORMANCE TEST // -------------------------------------------------------------------- bsls::Stopwatch t; @@ -13861,9 +13850,9 @@ int main(int argc, char *argv[]) // - It should work with the NULL-terminator different from '\0' to // make sure that the implementation always uses char_type() default // constructor to terminate the string rather than a null literal. - // - // Testing: - // SHORT STRING OPTIMIZATION + // + // Testing: + // SHORT STRING OPTIMIZATION // -------------------------------------------------------------------- if (verbose) printf("\nTesting the short string optimization" "\n=====================================\n"); @@ -13890,7 +13879,7 @@ int main(int argc, char *argv[]) // REPRODUCING KNOWN BUG CAUSING SEGFAULT IN FIND // This is a problem with the native library, being pursued in DRQS // 16870796. This test will do nothing unless run in verbose mode. - // + // // Concerns: // That a known bug in string::find on Sun cc is reproduced in this // test suite. @@ -13930,11 +13919,11 @@ int main(int argc, char *argv[]) // CHAR_TRAITS. // - A bsl::basic_string and a native_std::basic_string with the // same template parameters will have the same npos value. - // + // // Testing: - // npos - // operator native_stl::string() const; - // string(const native_stl::basic_string&); + // npos + // operator native_stl::string() const; + // string(const native_stl::basic_string&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting conversions to/from native string" @@ -14091,7 +14080,7 @@ int main(int argc, char *argv[]) // // Testing: // void swap(string&); - // void swap(string&, string&); + // void swap(string&, string&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting 'swap'" @@ -14166,10 +14155,10 @@ int main(int argc, char *argv[]) // TESTING ERASE // // Testing: - // void pop_back(); - // iterator erase(size_type pos = 0, size_type n = npos); - // iterator erase(const_iterator p); - // iterator erase(const_iterator first, iterator last); + // void pop_back(); + // iterator erase(size_type pos = 0, size_type n = npos); + // iterator erase(const_iterator p); + // iterator erase(const_iterator first, iterator last); // -------------------------------------------------------------------- if (verbose) printf("\nTesting 'erase' and 'pop_back'" @@ -14198,14 +14187,14 @@ int main(int argc, char *argv[]) // TESTING INSERTION // // Testing: - // string& insert(size_type pos1, const string& str); - // string& insert(size_type pos1, const string& str, pos2, n); - // string& insert(size_type pos, const C *s, n2); - // string& insert(size_type pos, const C *s); - // string& insert(size_type pos, size_type n, C c); - // iterator insert(const_iterator p, C c); - // iterator insert(const_iterator p, size_type n, C c); - // template iterator insert(citer,IIter,IIter); + // string& insert(size_type pos1, const string& str); + // string& insert(size_type pos1, const string& str, pos2, n); + // string& insert(size_type pos, const C *s, n2); + // string& insert(size_type pos, const C *s); + // string& insert(size_type pos, size_type n, C c); + // iterator insert(const_iterator p, C c); + // iterator insert(const_iterator p, size_type n, C c); + // template iterator insert(citer,IIter,IIter); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Value Insertion" @@ -14253,11 +14242,11 @@ int main(int argc, char *argv[]) // TESTING APPEND // // Testing: - // string& append(const string& str); - // string& append(const string& str, pos, n); - // string& append(const C *s, size_type n); - // string& append(const C *s); - // string& append(size_type n, C c); + // string& append(const string& str); + // string& append(const string& str, pos, n); + // string& append(const C *s, size_type n); + // string& append(const C *s); + // string& append(size_type n, C c); // template string& append(IIter,IIter); // -------------------------------------------------------------------- @@ -14367,7 +14356,7 @@ int main(int argc, char *argv[]) // Testing: // void resize(size_type n); // void resize(size_type n, C c); - // void reserve(size_type n); + // void reserve(size_type n); // size_type max_size() const; // size_type capacity() const; // bool empty() const; @@ -14388,12 +14377,12 @@ int main(int argc, char *argv[]) // TESTING ASSIGNMENT // // Testing: - // void assign(const string& str); - // void assign(const string& str, pos, n); - // void assign(const C *s, size_type n); - // void assign(const C *s); - // void assign(size_type n, C c); - // template void assign(IIter,IIter); + // void assign(const string& str); + // void assign(const string& str, pos, n); + // void assign(const C *s, size_type n); + // void assign(const C *s); + // void assign(size_type n, C c); + // template void assign(IIter,IIter); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Initial-Length Assignment" @@ -14441,11 +14430,11 @@ int main(int argc, char *argv[]) // TESTING CONSTRUCTORS // // Testing: - // string(const string& str, pos, n = npos, a = A()); - // string(const C *s, n, a = A()); - // string(const C *s, a = A()); - // string(n, C c, a = A()); - // template string(InputIter,InputIter,a = A()); + // string(const string& str, pos, n = npos, a = A()); + // string(const C *s, n, a = A()); + // string(const C *s, a = A()); + // string(n, C c, a = A()); + // template string(InputIter,InputIter,a = A()); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Initial-Length Constructor" @@ -14528,9 +14517,9 @@ int main(int argc, char *argv[]) // See that function for a list of concerns and a test plan. // // Testing: - // operator=(const string& rhs); - // operator=(const C *s); - // operator=(c); + // operator=(const string& rhs); + // operator=(const C *s); + // operator=(c); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Assignment Operator" @@ -14567,8 +14556,8 @@ int main(int argc, char *argv[]) // that function for a list of concerns and a test plan. // // Testing: - // string g(const char *spec); - // string g(size_t len, TYPE seed); + // string g(const char *spec); + // string g(size_t len, TYPE seed); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Generator Function g" @@ -14621,11 +14610,11 @@ int main(int argc, char *argv[]) // // Testing: // bool operator==(const string&, const string&); - // bool operator==(const C *, const string&); - // bool operator==(const string&, const C *); - // bool operator!=(const string&, const string&); - // bool operator!=(const C *, const string&); - // bool operator!=(const string&, const C *); + // bool operator==(const C *, const string&); + // bool operator==(const string&, const C *); + // bool operator!=(const string&, const string&); + // bool operator!=(const C *, const string&); + // bool operator!=(const string&, const C *); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Equality Operators" @@ -14675,8 +14664,8 @@ int main(int argc, char *argv[]) // for a list of concerns and a test plan. // // Testing: - // const_reference operator[](size_type pos) const; - // const_reference at(size_type pos) const; + // const_reference operator[](size_type pos) const; + // const_reference at(size_type pos) const; // size_type size() const; // -------------------------------------------------------------------- @@ -14698,8 +14687,8 @@ int main(int argc, char *argv[]) // function for a list of concerns and a test plan. // // Testing: - // int ggg(string *object, const char *spec, int vF = 1); - // string& gg(string *object, const char *spec); + // int ggg(string *object, const char *spec, int vF = 1); + // string& gg(string *object, const char *spec); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Generator Functions" @@ -14876,7 +14865,7 @@ int main(int argc, char *argv[]) // access patterns, function call frequencies, etc. // // Testing: - // PERFORMANCE TEST + // PERFORMANCE TEST // -------------------------------------------------------------------- if (verbose) printf("\nTesting Performance" From cb4aba84d83184704edda284f5b77c94554ce82d Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 23:19:58 -0500 Subject: [PATCH 18/49] Make 'Testing:' label target match Test Plan Checklist --- groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index 3597beef06..cee1da49ff 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -791,7 +791,7 @@ int main(int argc, char *argv[]) // them. Make sure all memory is deallocated. (C-1) // // Testing: - // This test exercises the component but tests nothing. + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" From 747bbabf8d78486a1b8dd98473576cd4d074751f Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 23:23:02 -0500 Subject: [PATCH 19/49] Make 'Testing:' labels match Test Plan checklist --- groups/bsl/bslalg/bslalg_rangecompare.t.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp index 0805e7a9bc..6b37ff36e3 100644 --- a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp +++ b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp @@ -49,7 +49,7 @@ using namespace std; // [ 3] bool equal(start1, end1, start2, end2); // [ 3] bool equal(start1, end1, length1, start2, end2, length2); // [ 4] bool lexicographical(start1, end1, start2, end2); -// [ 4] bool lexicographical(start1, end1, length1, start2, end2, length2); +// [ 4] bool lexicographical(s1, end1, length1, s2, end2, length2); //----------------------------------------------------------------------------- // [ 1] BREATHING TEST // [ 2] TEST APPARATUS @@ -2152,7 +2152,7 @@ int main(int argc, char *argv[]) // // Testing: // bool lexicographical(start1, end1, start2, end2); - // bool lexicographical(start1, end1, length1, start2, end2, length2); + // bool lexicographical(s1, end1, length1, s2, end2, length2); // -------------------------------------------------------------------- if (verbose) printf("\nTESTING 'lexicographical'" From 7c983ca334342283950b3397bbcd98f76376c45d Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Mon, 7 Jan 2013 23:26:37 -0500 Subject: [PATCH 20/49] Add Below the Line checklist item [22] CONCERN: Vector support types with overloaded new/delete Make 'Testing:' label target match Test Plan Checklist --- groups/bsl/bslstl/bslstl_vector.t.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_vector.t.cpp b/groups/bsl/bslstl/bslstl_vector.t.cpp index e0feea9644..2557d0a513 100644 --- a/groups/bsl/bslstl/bslstl_vector.t.cpp +++ b/groups/bsl/bslstl/bslstl_vector.t.cpp @@ -150,6 +150,7 @@ using namespace bsl; // [11] ALLOCATOR-RELATED CONCERNS // [18] USAGE EXAMPLE // [21] CONCERN: 'std::length_error' is used properly +// [22] CONCERN: Vector support types with overloaded new/delete // // TEST APPARATUS: GENERATOR FUNCTIONS // [ 3] int ggg(vector *object, const char *spec, int vF = 1); @@ -1850,7 +1851,7 @@ void TestDriver::testCase22() //: 4 Destroy any vecto5rs that was created. // // Testing: - // CONCERN: Vector support types with overloaded new/delete + // CONCERN: Vector support types with overloaded new/delete // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -1916,7 +1917,7 @@ void TestDriver::testCase21() // size that is guaranteed to result in a value exceeding 'max_size()'. // // Testing: - // Proper use of 'std::length_error' + // CONCERN: 'std::length_error' is used properly // ------------------------------------------------------------------------ bslma::TestAllocator testAllocator(veryVeryVerbose); From 6741e772760bb2f000884dfe5c90c52552ebd145 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 08:00:07 -0500 Subject: [PATCH 21/49] replace tabs with 8 spaces --- groups/bsl/bsls/bsls_ident.t.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/groups/bsl/bsls/bsls_ident.t.cpp b/groups/bsl/bsls/bsls_ident.t.cpp index e86c4636fc..cf4d15bb1f 100644 --- a/groups/bsl/bsls/bsls_ident.t.cpp +++ b/groups/bsl/bsls/bsls_ident.t.cpp @@ -150,9 +150,9 @@ int main(int argc, char *argv[]) // // Plan: // Do nothing. - // - // Testing: - // BREATHING TEST + // + // Testing: + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) std::cout << "\nBREATHING TEST" From 17d450736e75a3027d4f772aaea93cfdf3f58aac Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 08:01:59 -0500 Subject: [PATCH 22/49] replace tabs with 8 spaces --- groups/bsl/bslalg/bslalg_rangecompare.t.cpp | 2 +- groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp index 6b37ff36e3..62faac8076 100644 --- a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp +++ b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp @@ -2497,7 +2497,7 @@ int main(int argc, char *argv[]) // can be used. Display the resulting times. // // Testing: - // PERFORMANCE TEST + // PERFORMANCE TEST // -------------------------------------------------------------------- if (verbose) printf("\nPERFORMANCE TEST" diff --git a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp index 4777fff7c0..c9852b8cfc 100644 --- a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +++ b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp @@ -4,8 +4,6 @@ #include #include // yes, we want the native std here - - #include #include #include From eb41c3f59083d5f14d9777650fded44ad4b7ccad Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 08:44:57 -0500 Subject: [PATCH 23/49] List of files we are focused on remediating --- targetFiles | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 targetFiles diff --git a/targetFiles b/targetFiles new file mode 100644 index 0000000000..c1d5c93ea8 --- /dev/null +++ b/targetFiles @@ -0,0 +1,11 @@ +./groups/bsl/bslstl/bslstl_stringbuf.t.cpp +./groups/bsl/bslstl/bslstl_deque.t.cpp +./groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +./groups/bsl/bslstl/bslstl_pair.t.cpp +./groups/bsl/bslstl/bslstl_string.t.cpp +./groups/bsl/bslstl/bslstl_vector.t.cpp +./groups/bsl/bslalg/bslalg_rangecompare.t.cpp +./groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp +./groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +./groups/bsl/bsls/bsls_alignedbuffer.t.cpp +./groups/bsl/bsls/bsls_ident.t.cpp From 5394dc4c0b9458aa77250675db9f209b3b795bdb Mon Sep 17 00:00:00 2001 From: Fei-Tzin Lee Date: Tue, 8 Jan 2013 10:39:23 -0500 Subject: [PATCH 24/49] Added overview. Exhaustive and area tests have not been implemented in cases. --- groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp | 30 ++++++++++++++------ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp index c9852b8cfc..f3078f088c 100644 --- a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +++ b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp @@ -11,16 +11,30 @@ using namespace BloombergLP; using namespace std; -//============================================================================= +// ============================================================================= // TEST PLAN -//----------------------------------------------------------------------------- -// -// -//----------------------------------------------------------------------------- - -//========================================================================== +// ----------------------------------------------------------------------------- +// Overview +// -------- +// 'bslstl::StdExceptUtil' is a utility-type class. To test it, we follow the +// standard order of testing for utility classes. The approach for testing this +// sort of class is to implement a breathing test to test basic functionality; +// an exhaustive test for the entire possible range of inputs; an area test for +// the meaningful, primary range of inputs; and a usage example to test the +// functionality necessary for the programmer to use the component. The custom +// test apparatuses used are 'testFunction()', a templated free function which +// throws various exceptions, and 'callTestFunction()', which essentially tests +// 'testFunction()'. +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// [ 1] BREATHING TEST +// [ 2] Exhaustively test whole input range +// [ 3] Area test meaningful input range +// [ 4] USAGE EXAMPLE +// ========================================================================== // STANDARD BDE ASSERT TEST MACRO -//-------------------------------------------------------------------------- +// -------------------------------------------------------------------------- // NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY // FUNCTIONS, INCLUDING IOSTREAMS. static int testStatus = 0; From d8aea48b2b4d26c8ea4f05c1433a5c962f6faf69 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 12:43:25 -0500 Subject: [PATCH 25/49] Update Overview making it more explicit as to how the process applies to this particular class. --- groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp | 39 ++++++++++++-------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp index f3078f088c..3bc40cbb49 100644 --- a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +++ b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp @@ -12,26 +12,35 @@ using namespace BloombergLP; using namespace std; // ============================================================================= -// TEST PLAN +// TEST PLAN // ----------------------------------------------------------------------------- -// Overview -// -------- -// 'bslstl::StdExceptUtil' is a utility-type class. To test it, we follow the -// standard order of testing for utility classes. The approach for testing this -// sort of class is to implement a breathing test to test basic functionality; -// an exhaustive test for the entire possible range of inputs; an area test for -// the meaningful, primary range of inputs; and a usage example to test the -// functionality necessary for the programmer to use the component. The custom -// test apparatuses used are 'testFunction()', a templated free function which -// throws various exceptions, and 'callTestFunction()', which essentially tests -// 'testFunction()'. +// Overview +// -------- +// 'bslstl::StdExceptUtil' is a 'Type only' utility class. To test it, we follow +// the standard order of testing for 'Type only' classes. The approach for +// testing this sort of class is to implement the following +// +//: o a BREATHING TEST where we demonstrate the basic functionality of the +// 'bslstl::StdExceptUtil' +//: +//: o an EXHAUSTIVE INPUT TEST for the entire possible range of inputs. In this +//: case, the entire range of inputs is also tested in the BREATHING TEST. +//: +//: o an AREA TEST for the meaningful, primary range of inputs. In this Test +//: Driver, all meaningful ranges of inputs are covered by the BREATHING TEST +//: as well. +//: +//: o an USAGE EXAMPLE to demonstrate a working example of how a programmer +//: might use the component. +// +// The custom test apparatuses used are 'testFunction()', a templated free +// function which throws various exceptions, and 'callTestFunction()', which +// executes 'testFunction()'. // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- // [ 1] BREATHING TEST -// [ 2] Exhaustively test whole input range -// [ 3] Area test meaningful input range -// [ 4] USAGE EXAMPLE +// [ 2] USAGE EXAMPLE // ========================================================================== // STANDARD BDE ASSERT TEST MACRO // -------------------------------------------------------------------------- From 537c0a279305c099237ce6e654b72b70fb4c3dd2 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 12:45:53 -0500 Subject: [PATCH 26/49] make 'Testing:' label targets match the Test Plan checklist letter for letter. --- groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp index 3bc40cbb49..fa5ff9018b 100644 --- a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +++ b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp @@ -172,7 +172,7 @@ int main(int argc, char *argv[]) // Plan: // // Testing: - // + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" From 025bb21ada834af713c124ac30d2530921cfd76e Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 14:04:28 -0500 Subject: [PATCH 27/49] update all 'Testing:' label targets in switch to match Test Plan checklist Shortened some multilined template names Note: some cases are effectively noops (eg. case 5 and case 10) I see multiple ways of representing 'const references' in the Test Plan 1 const_references 2 const T& it seems we should standardize how this is done. --- groups/bsl/bslstl/bslstl_vector.t.cpp | 99 ++++++++++++++------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_vector.t.cpp b/groups/bsl/bslstl/bslstl_vector.t.cpp index 2557d0a513..e9040cc182 100644 --- a/groups/bsl/bslstl/bslstl_vector.t.cpp +++ b/groups/bsl/bslstl/bslstl_vector.t.cpp @@ -83,19 +83,17 @@ using namespace bsl; // [ 2] vector(const A& a = A()); // [12] vector(size_type n, const A& a = A()); // [12] vector(size_type n, const T& val, const A& a = A()); -// [12] template -// vector(InputIter first, InputIter last, const A& a = A()); +// [12] template vector(IIter,IIter,const A& a = A()); // [ 7] vector(const vector& orig, const A& = A()); // [12] vector(vector&& original); // [ 2] ~vector(); // /// MANIPULATORS: -// [13] template -// void assign(InputIter first, InputIter last); +// [13] template void assign(IIter,IIter); // [13] void assign(size_type numElements, const T& val); // [ 9] operator=(vector&); -// [15] reference operator[](size_type pos); -// [15] reference at(size_type pos); +// [15] T& operator[](size_type pos); +// [15] T& at(size_type pos); // [16] iterator begin(); // [16] iterator end(); // [16] reverse_iterator rbegin(); @@ -104,8 +102,8 @@ using namespace bsl; // [14] void resize(size_type n, const T& val); // [14] void reserve(size_type n); // [ 2] void clear(); -// [15] reference front(); -// [15] reference back(); +// [15] T& front(); +// [15] T& back(); // [ ] VALUE_TYPE *data(); // [20] template // iterator emplace(const_iterator pos, Args...); @@ -114,8 +112,7 @@ using namespace bsl; // [18] void pop_back(); // [17] iterator insert(const_iterator pos, const T& val); // [17] iterator insert(const_iterator pos, size_type n, const T& val); -// [17] template -// void insert(const_iterator pos, InputIter first, InputIter last); +// [17] template void insert(constIter,IIter,IIter); // [18] iterator erase(const_iterator pos); // [18] iterator erase(const_iterator first, const_iterator last); // [19] void swap(vector&); @@ -123,17 +120,17 @@ using namespace bsl; // ACCESSORS: // [ 4] const_reference operator[](size_type pos) const; // [ 4] const_reference at(size_type pos) const; -// [15] const_reference front() const; -// [15] const_reference back() const; +// [15] const T& front() const; +// [15] const T& back() const; // [ ] const VALUE_TYPE *data() const; // [ 4] size_type size() const; // [14] size_type max_size() const; // [14] size_type capacity() const; // [14] bool empty() const; -// [16] const_iterator begin(); -// [16] const_iterator end(); -// [16] const_reverse_iterator rbegin(); -// [16] const_reverse_iterator rend(); +// [16] const_iterator begin() const; +// [16] const_iterator end() const; +// [16] const_reverse_iterator rbegin() const; +// [16] const_reverse_iterator rend() const; // // FREE OPERATORS: // [ 6] bool operator==(const vector&, const vector&); @@ -8479,7 +8476,7 @@ int main(int argc, char *argv[]) // TESTING COMPARISON FREE OPERATORS // // Testing: - // bool operator<(const vector& lhs, const vector& rhs); + // bool operator<(const vector&, const vector&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting comparison free operators" @@ -8497,10 +8494,10 @@ int main(int argc, char *argv[]) // TESTING SWAP // // Testing: - // void swap(Vector_Imp&); - // void swap(vector& lhs, vector& rhs); - // void swap(vector&& lhs, vector& rhs); - // void swap(vector& lhs, vector&& rhs); + // void swap(vector&); + // void swap(vector&, vector&); + // void swap(vector&, vector&&); + // void swap(vector&&, vector&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting 'swap'" @@ -8514,7 +8511,7 @@ int main(int argc, char *argv[]) // TESTING ERASE // // Testing: - // iterator erase(const_iterator position); + // iterator erase(const_iterator pos); // iterator erase(const_iterator first, const_iterator last); // void pop_back(); // -------------------------------------------------------------------- @@ -8561,11 +8558,10 @@ int main(int argc, char *argv[]) // TESTING INSERTION // // Testing: - // void push_back(T&& value); - // iterator insert(const_iterator position, const T& value); - // void insert(const_iterator pos, size_type n, const T& val); - // template - // void insert(const_iterator pos, InputIter first, InputIter last); + // void push_back(T&&); + // iterator insert(const_iterator pos, const T& val); + // iterator insert(const_iterator pos, size_type n, const T& val); + // template void insert(constIter,IIter,IIter); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Value Insertion" @@ -8666,8 +8662,8 @@ int main(int argc, char *argv[]) // TESTING ELEMENT ACCESS // // Testing: - // T& operator[](size_type position); - // T& at(size_type n); + // T& operator[](size_type pos); + // T& at(size_type pos); // T& front(); // T& back(); // const T& front() const; @@ -8699,8 +8695,9 @@ int main(int argc, char *argv[]) // TESTING CAPACITY // // Testing: + // void resize(size_type n); + // void resize(size_type n, const T& val); // void reserve(size_type n); - // void resize(size_type n, T val); // size_type max_size() const; // size_type capacity() const; // bool empty() const; @@ -8721,9 +8718,8 @@ int main(int argc, char *argv[]) // TESTING ASSIGNMENT // // Testing: - // void assign(size_t n, const T& val); - // template - // void assign(InputIter first, InputIter last); + // template void assign(IIter,IIter); + // void assign(size_type numElements, const T& val); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Initial-Length Assignment" @@ -8848,10 +8844,10 @@ int main(int argc, char *argv[]) // correct overload was called should suffice. // // Testing: - // vector(size_type n, const T& val = T(), const A& a = A()); - // template - // vector(InputIter first, InputIter last, const A& a = A()); - // vector(vector&& original); + // [12] vector(size_type n, const A& a = A()); + // [12] vector(size_type n, const T& val, const A& a = A()); + // [12] template vector(IIter,IIter,const A& a = A()); + // [12] vector(vector&& original); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Initial-Length Constructor" @@ -8924,6 +8920,8 @@ int main(int argc, char *argv[]) // TESTING ALLOCATOR-RELATED CONCERNS // // Testing: + // TRAITS + // ALLOCATOR-RELATED CONCERNS // -------------------------------------------------------------------- if (verbose) printf("\nTesting Allocator concerns" @@ -8935,6 +8933,10 @@ int main(int argc, char *argv[]) case 10: { // -------------------------------------------------------------------- // TESTING STREAMING FUNCTIONALITY: + // + // + // Testing: + // // -------------------------------------------------------------------- if (verbose) printf("\nTesting Streaming Functionality" @@ -8954,7 +8956,7 @@ int main(int argc, char *argv[]) // See that function for a list of concerns and a test plan. // // Testing: - // Obj& operator=(const Obj& rhs); + // operator=(vector&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Assignment Operator" @@ -8980,7 +8982,7 @@ int main(int argc, char *argv[]) // that function for a list of concerns and a test plan. // // Testing: - // Obj g(const char *spec); + // vector g(const char *spec); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Generator Function g" @@ -9012,8 +9014,7 @@ int main(int argc, char *argv[]) // that function for a list of concerns and a test plan. // // Testing: - // Vector_Imp(const Vector_Imp& original); - // Vector_Imp(const Vector_Imp& original, alloc); + // vector(const vector& orig, const A& = A()); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Copy Constructors" @@ -9051,7 +9052,8 @@ int main(int argc, char *argv[]) // plan. // // Testing: - // operator==(const Obj&, const Obj&); + // bool operator==(const vector&, const vector&); + // bool operator!=(const vector&, const vector&); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Equality Operators" @@ -9093,8 +9095,9 @@ int main(int argc, char *argv[]) // for a list of concerns and a test plan. // // Testing: - // int size() const; - // const int& operator[](int index) const; + // const_reference operator[](size_type pos) const; + // const_reference at(size_type pos) const; + // size_type size() const; // -------------------------------------------------------------------- if (verbose) printf("\nTesting Basic Accessors" @@ -9124,8 +9127,8 @@ int main(int argc, char *argv[]) // function for a list of concerns and a test plan. // // Testing: - // void ggg(Obj *object, const char *spec); - // Obj& gg(Obj *object, const char *spec, ); + // int ggg(vector *object, const char *spec, int vF = 1); + // vector& gg(vector *object, const char *spec); // -------------------------------------------------------------------- if (verbose) printf("\nTesting Generator Functions" @@ -9159,7 +9162,7 @@ int main(int argc, char *argv[]) // plan. // // Testing: - // void push_back(T const& v); + // void push_back(const T&); // void clear(); // -------------------------------------------------------------------- @@ -9195,7 +9198,7 @@ int main(int argc, char *argv[]) // work as expected in normal operation. // // Testing: - // This "test" *exercises* basic functionality. + // BREATHING TEST // -------------------------------------------------------------------- if (verbose) printf("\nBREATHING TEST" From 52b4b3d1624de521e5cff2eb6c1bc15e07c2d465 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 15:31:21 -0500 Subject: [PATCH 28/49] update all testCase functions' 'Testing:' labels to match the Test Plan Checklist replace all 'const_reference' instance with 'const T&' update const T& operator[](size_type pos) const to be fully checked in test case 15 not 4 There is a strange 2 line checklist item that seems unused // [20] template // iterator emplace(const_iterator pos, Args...); --- groups/bsl/bslstl/bslstl_vector.t.cpp | 104 +++++++++++++------------- 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_vector.t.cpp b/groups/bsl/bslstl/bslstl_vector.t.cpp index e9040cc182..1149e6783c 100644 --- a/groups/bsl/bslstl/bslstl_vector.t.cpp +++ b/groups/bsl/bslstl/bslstl_vector.t.cpp @@ -104,9 +104,7 @@ using namespace bsl; // [ 2] void clear(); // [15] T& front(); // [15] T& back(); -// [ ] VALUE_TYPE *data(); -// [20] template -// iterator emplace(const_iterator pos, Args...); +// [15] VALUE_TYPE *data(); // [ 2] void push_back(const T&); // [17] void push_back(T&&); // [18] void pop_back(); @@ -118,11 +116,11 @@ using namespace bsl; // [19] void swap(vector&); // // ACCESSORS: -// [ 4] const_reference operator[](size_type pos) const; -// [ 4] const_reference at(size_type pos) const; +// [15] const T& operator[](size_type pos) const; +// [15] const T& at(size_type pos) const; // [15] const T& front() const; // [15] const T& back() const; -// [ ] const VALUE_TYPE *data() const; +// [15] const VALUE_TYPE *data() const; // [ 4] size_type size() const; // [14] size_type max_size() const; // [14] size_type capacity() const; @@ -2453,7 +2451,7 @@ void TestDriver::testCase19() // Verify that memory was returned to allocator. // // Testing: - // swap(vector& lhs, vector& rhs); + // void swap(vector&, vector&); // ------------------------------------------------------------------------ if (verbose) printf("\nSWAP TEST" @@ -2995,7 +2993,7 @@ void TestDriver::testCase18Negative() // // Testing: // void pop_back(); - // iterator erase(const_iterator p); + // iterator erase(const_iterator pos); // iterator erase(const_iterator first, iterator last); // ----------------------------------------------------------------------- @@ -3120,10 +3118,10 @@ void TestDriver::testCase17() // identical to t it would be if the value had not been aliased. // // Testing: - // iterator insert(const_iterator pos, const T& value); - // void insert(const_iterator pos, size_type n, const T& value); - // void push_back(T&& value); - // void insert(const_iterator pos, size_type n, T&& value); + // void push_back(T&&); + // iterator insert(const_iterator pos, const T& val); + // iterator insert(const_iterator pos, size_type n, const T& val); + // template void insert(constIter,IIter,IIter); // ----------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -3884,10 +3882,10 @@ void TestDriver::testCase17Negative() // with invalid iterators and verify that it asserts. // // Testing: + // void push_back(T&&); // iterator insert(const_iterator pos, const T& val); // iterator insert(const_iterator pos, size_type n, const T& val); - // template - // void insert(const_iterator pos, InputIter first, InputIter last); + // template void insert(constIter,IIter,IIter); // ----------------------------------------------------------------------- const typename Obj::const_iterator badIterator = @@ -4010,10 +4008,10 @@ void TestDriver::testCase16() // iterator end(); // reverse_iterator rbegin(); // reverse_iterator rend(); - // const_iterator begin(); - // const_iterator end(); - // const_reverse_iterator rbegin(); - // const_reverse_iterator rend(); + // const_iterator begin() const; + // const_iterator end() const; + // const_reverse_iterator rbegin() const; + // const_reverse_iterator rend() const; // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -4146,16 +4144,16 @@ void TestDriver::testCase15() // specified index to the pointer returned by 'data()'. // // Testing: - // T& operator[](size_type position); - // T& at(size_type n); + // T& operator[](size_type pos); + // T& at(size_type pos); // T& front(); // T& back(); - // T *data(); - // const T& operator[](size_type position) const; - // const T& at(size_type n) const; + // VALUE_TYPE *data(); + // const T& operator[](size_type pos) const; + // const T& at(size_type pos) const; // const T& front() const; // const T& back() const; - // const T *data() const; + // const VALUE_TYPE *data() const; // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -4278,10 +4276,10 @@ void TestDriver::testCase15Negative() // index is out of range. // // Testing: - // T& operator[](size_type position); - // const T& operator[](size_type position) const; + // T& operator[](size_type pos); // T& front(); // T& back(); + // const T& operator[](size_type pos) const; // const T& front() const; // const T& back() const; // -------------------------------------------------------------------- @@ -4387,8 +4385,8 @@ void TestDriver::testCase14() // each test in the standard 'bslma' exception-testing macro block. // // Testing: - // void Vector_Imp::reserve(size_type n); - // void resize(size_type n, T val = T()); + // void resize(size_type n, const T& val); + // void reserve(size_type n); // size_type max_size() const; // size_type capacity() const; // bool empty() const; @@ -4669,7 +4667,7 @@ void TestDriver::testCase13() // completely in test case 17. // // Testing: - // assign(size_type n, const T& value); + // void assign(size_type numElements, const T& val); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -4845,8 +4843,7 @@ void TestDriver::testCase13Range(const CONTAINER&) // completely in test case 17. // // Testing: - // template - // assign(InputIter first, InputIter last); + // template void assign(IIter,IIter); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -5034,8 +5031,7 @@ void TestDriver::testCase13Negative(const CONTAINER&) // where the specified iterators are in the reversed order. // // Testing: - // template - // assign(InputIter first, InputIter last); + // template void assign(IIter,IIter); // -------------------------------------------------------------------- bsls::AssertFailureHandlerGuard guard(&bsls::AssertTest::failTestDriver); @@ -5107,9 +5103,9 @@ void TestDriver::testCase12() // expected, and that no allocation was performed. // // Testing: - // Vector_Imp(size_type n, const A& a = A()); - // Vector_Imp(size_type n, const T& value, const A& a = A()); - // Vector_Imp(vector&& original); + // vector(size_type n, const A& a = A()); + // vector(size_type n, const T& val, const A& a = A()); + // vector(vector&& original); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -5526,8 +5522,7 @@ void TestDriver::testCase12Range(const CONTAINER&) // reverse-ordered ranges. // // Testing: - // template - // Vector_Imp(InputIter first, InputIter last, const A& a = A()); + // template vector(IIter,IIter,const A& a = A()); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -5810,15 +5805,16 @@ void TestDriver::testCase11() // We first verify that the 'Vector_Imp' class has the traits, and // that allocator // - // Testing: - // TRAITS - // // TBD When a new vector object Y is created from an old vector object // X, then the standard states that Y should get its allocator by // copying X's allocator (23.1, Point 8). Our vector implementation // does not follow this rule for 'bslma::Allocator'-based allocators. // To verify this behavior for non-'bslma::Allocator', should test // copy constructor using one and verify standard is followed. + // + // Testing: + // TRAITS + // ALLOCATOR-RELATED CONCERNS // -------------------------------------------------------------------- if (verbose) printf("\nALLOCATOR TEST" @@ -5914,7 +5910,7 @@ void TestDriver::testCase9() // With allocator, not moveable // // Testing: - // vector& operator=(const vector& rhs); + // operator=(vector&); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -6212,7 +6208,7 @@ void TestDriver::testCase8() // returned by 'g' differs in size from that returned by 'gg'. // // Testing: - // Vector_Imp g(const char *spec); + // vector g(const char *spec); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -6319,7 +6315,7 @@ void TestDriver::testCase7() // 'bslma::TestAllocator' and varying its *allocation* *limit*. // // Testing: - // vector(const vector& original); + // vector(const vector& orig, const A& = A()); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -6651,8 +6647,8 @@ void TestDriver::testCase6() // trait or not. // // Testing: - // operator==(const vector&, const vector&); - // operator!=(const vector&, const vector&); + // bool operator==(const vector&, const vector&); + // bool operator!=(const vector&, const vector&); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator1(veryVeryVerbose); @@ -6836,10 +6832,10 @@ void TestDriver::testCase4() // Note - Using untested resize(int). // // Testing: - // reference operator[](size_type pos); - // const_reference operator[](size_type pos) const; - // reference at(size_type pos); - // const_reference at(size_type pos) const; + // T& operator[](size_type pos); + // const T& operator[](size_type pos) const; + // T& at(size_type pos); + // const T& at(size_type pos) const; // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -7163,8 +7159,8 @@ void TestDriver::testCase3() // parser only; the primary manipulators are already assumed to work. // // Testing: - // vector& gg(vector *object, const char *spec); // int ggg(vector *object, const char *spec, int vF = 1); + // vector& gg(vector *object, const char *spec); // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -7815,7 +7811,7 @@ void TestDriver::testCase1() // 11) Assign x4 = x4 (aliasing). { x1: x2: x3:AB x4:AB } // // Testing: - // This "test" *exercises* basic functionality. + // BREATHING TEST // -------------------------------------------------------------------- bslma::TestAllocator testAllocator(veryVeryVerbose); @@ -9095,8 +9091,8 @@ int main(int argc, char *argv[]) // for a list of concerns and a test plan. // // Testing: - // const_reference operator[](size_type pos) const; - // const_reference at(size_type pos) const; + // const T& operator[](size_type pos) const; + // const T& at(size_type pos) const; // size_type size() const; // -------------------------------------------------------------------- From 91b9e1f75243d64ef3617d75186d634cd1ffc09a Mon Sep 17 00:00:00 2001 From: WeiYeh Date: Tue, 8 Jan 2013 17:03:22 -0500 Subject: [PATCH 29/49] substituting inline defined macros to standard macros --- .../bslalg_arraydestructionprimitives.t.cpp | 61 ++++++++++--------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index cee1da49ff..fb9e1a794f 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -11,8 +11,10 @@ #include // for testing only #include // for testing only #include // for testing only +#include #include // for testing only #include // for testing only + #include #include // atoi() @@ -61,35 +63,36 @@ void aSsErT(int c, const char *s, int i) } } // close unnamed namespace -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } -//============================================================================= -// STANDARD BDE LOOP-ASSERT TEST MACROS -//----------------------------------------------------------------------------- -// NOTE: This implementation of LOOP_ASSERT macros must use printf since -// cout uses new and be called during exception testing. -#define LOOP_ASSERT(I,X) { \ - if (!(X)) { printf("%s: %d\n", #I, I); aSsErT(1, #X, __LINE__); } } - -#define LOOP2_ASSERT(I,J,X) { \ - if (!(X)) { printf("%s: %d\t%s: %d\n", #I, I, #J, J); \ - aSsErT(1, #X, __LINE__); } } - -#define LOOP3_ASSERT(I,J,K,X) { \ - if (!(X)) { printf("%s: %d\t%s: %c\t%s: %c\n", #I, I, #J, J, #K, K); \ - aSsErT(1, #X, __LINE__); } } - -#define LOOP4_ASSERT(I,J,K,L,X) { \ - if (!(X)) { printf("%s: %d\t%s: %d\t%s: %d\t%s: %d\n", \ - #I, I, #J, J, #K, K, #L, L); aSsErT(1, #X, __LINE__); } } - -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. -#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. -//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ printf("\t"); // Print a tab (w/o newline) +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number + +//============================================================================= +// SEMI-STANDARD NEGATIVE-TESTING MACROS +//----------------------------------------------------------------------------- +#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) +#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) +#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) +#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) +#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) +#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) //============================================================================= // SEMI-STANDARD NEGATIVE-TESTING MACROS From 6096ec0de35535bb4feb45552b0cd86c53b0b232 Mon Sep 17 00:00:00 2001 From: Wei-yeh Lee Date: Tue, 8 Jan 2013 18:32:06 -0500 Subject: [PATCH 30/49] substituting inline defined macros with standard macros in header files --- .../bslalg_scalardestructionprimitives.t.cpp | 67 ++++++------------- 1 file changed, 21 insertions(+), 46 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp index 0bf0fedba0..cc50319d53 100644 --- a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp @@ -11,6 +11,7 @@ #include // for testing only #include // for testing only #include // for testing only +#include #include // for testing only #include // for testing only @@ -42,52 +43,26 @@ using namespace BloombergLP; //----------------------------------------------------------------------------- // [ 1] BREATHING TEST -//============================================================================= -// STANDARD BDE ASSERT TEST MACRO -//----------------------------------------------------------------------------- -// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY -// FUNCTIONS, INCLUDING IOSTREAMS. -int testStatus = 0; - -namespace { -void aSsErT(int c, const char *s, int i) -{ - if (c) { - printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); - if (testStatus >= 0 && testStatus <= 100) ++testStatus; -} -} -} // close unnamed namespace - -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } -//============================================================================= -// STANDARD BDE LOOP-ASSERT TEST MACROS -//----------------------------------------------------------------------------- -// NOTE: This implementation of LOOP_ASSERT macros must use printf since -// cout uses new and be called during exception testing. -#define LOOP_ASSERT(I,X) { \ - if (!(X)) { printf("%s: %d\n", #I, I); aSsErT(1, #X, __LINE__); } } - -#define LOOP2_ASSERT(I,J,X) { \ - if (!(X)) { printf("%s: %d\t%s: %d\n", #I, I, #J, J); \ - aSsErT(1, #X, __LINE__); } } - -#define LOOP3_ASSERT(I,J,K,X) { \ - if (!(X)) { printf("%s: %d\t%s: %c\t%s: %c\n", #I, I, #J, J, #K, K); \ - aSsErT(1, #X, __LINE__); } } - -#define LOOP4_ASSERT(I,J,K,L,X) { \ - if (!(X)) { printf("%s: %d\t%s: %d\t%s: %d\t%s: %d\n", \ - #I, I, #J, J, #K, K, #L, L); aSsErT(1, #X, __LINE__); } } - -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. -#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. -//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ printf("\t"); // Print a tab (w/o newline) +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // SEMI-STANDARD NEGATIVE-TESTING MACROS From 78c6ef441aef4f41643531b3f22a59422ffef498 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 19:55:06 -0500 Subject: [PATCH 31/49] substituting inline defined macros with standard macros in header files --- .../bslalg_arraydestructionprimitives.t.cpp | 1728 ++++++++--------- groups/bsl/bslalg/bslalg_rangecompare.t.cpp | 51 +- .../bslalg_scalardestructionprimitives.t.cpp | 1653 ++++++++-------- 3 files changed, 1715 insertions(+), 1717 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index fb9e1a794f..5651a6d4d4 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -1,68 +1,68 @@ -// bslalg_arraydestructionprimitives.t.cpp -*-C++-*- - -#include - -#include // for testing only - -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include -#include // for testing only -#include // for testing only - - -#include -#include // atoi() -#include // strlen() -#include // isalpha() - -using namespace BloombergLP; - -//============================================================================= -// TEST PLAN -//----------------------------------------------------------------------------- -// Overview -// -------- -// The component to be tested provides a single algorithm to destroy ranges. -// The main concern (besides that the objects are actually destroyed) is that -// the destructor calls are elided if the basic object type is bit-wise -// copyable. -// -// In order to facilitate the generation of test object instances, we make a -// text object have the value semantics of a 'char', and generate an array of -// test objects from a string specification via a generating function -// parameterized by the actual test object type. This lets us reuse the same -// test code for bitwise-copyable/moveable test types as well as those that do -// not have those traits. -//----------------------------------------------------------------------------- -// bslalg::ArrayPrimitives public interface: -// [ 2] void destroy(T *dstB, T *dstE); -//----------------------------------------------------------------------------- -// [ 1] BREATHING TEST - -//============================================================================= -// STANDARD BDE ASSERT TEST MACRO -//----------------------------------------------------------------------------- -// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY -// FUNCTIONS, INCLUDING IOSTREAMS. -int testStatus = 0; - -namespace { -void aSsErT(int c, const char *s, int i) -{ - if (c) - { - printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); - if (testStatus >= 0 && testStatus <= 100) ++testStatus; - } -} -} // close unnamed namespace - +// bslalg_arraydestructionprimitives.t.cpp -*-C++-*- + +#include + +#include // for testing only + +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include +#include // for testing only +#include // for testing only + + +#include +#include // atoi() +#include // strlen() +#include // isalpha() + +using namespace BloombergLP; + +//============================================================================= +// TEST PLAN +//----------------------------------------------------------------------------- +// Overview +// -------- +// The component to be tested provides a single algorithm to destroy ranges. +// The main concern (besides that the objects are actually destroyed) is that +// the destructor calls are elided if the basic object type is bit-wise +// copyable. +// +// In order to facilitate the generation of test object instances, we make a +// text object have the value semantics of a 'char', and generate an array of +// test objects from a string specification via a generating function +// parameterized by the actual test object type. This lets us reuse the same +// test code for bitwise-copyable/moveable test types as well as those that do +// not have those traits. +//----------------------------------------------------------------------------- +// bslalg::ArrayPrimitives public interface: +// [ 2] void destroy(T *dstB, T *dstE); +//----------------------------------------------------------------------------- +// [ 1] BREATHING TEST + +//============================================================================= +// STANDARD BDE ASSERT TEST MACRO +//----------------------------------------------------------------------------- +// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY +// FUNCTIONS, INCLUDING IOSTREAMS. +int testStatus = 0; + +namespace { +void aSsErT(int c, const char *s, int i) +{ + if (c) + { + printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); + if (testStatus >= 0 && testStatus <= 100) ++testStatus; + } +} +} // close unnamed namespace + //============================================================================= // STANDARD BDE TEST DRIVER MACROS //----------------------------------------------------------------------------- @@ -93,807 +93,797 @@ void aSsErT(int c, const char *s, int i) #define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) #define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) #define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) - -//============================================================================= -// SEMI-STANDARD NEGATIVE-TESTING MACROS -//----------------------------------------------------------------------------- -#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) -#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) -#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) -#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) -#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) -#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) - -//============================================================================= -// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING -//----------------------------------------------------------------------------- - -typedef bslalg::ArrayDestructionPrimitives Obj; - -// TYPES -class TestType; -class TestTypeNoAlloc; -class BitwiseCopyableTestType; - -typedef TestType T; // uses 'bslma' allocators -typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators -typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators - -typedef bsls::Types::Int64 Int64; -typedef bsls::Types::Uint64 Uint64; - -// STATIC DATA -static int verbose, veryVerbose, veryVeryVerbose; - -const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; - -static int numDefaultCtorCalls = 0; -static int numCharCtorCalls = 0; -static int numCopyCtorCalls = 0; -static int numAssignmentCalls = 0; -static int numDestructorCalls = 0; - -bslma::TestAllocator *Z; // initialized at the start of main() - - // ============== - // class TestType - // ============== - -class TestType { - // This test type contains a 'char' in some allocated storage. It counts - // the number of default and copy constructions, assignments, and - // destructions. It has no traits other than using a 'bslma' allocator. - // It could have the bit-wise moveable traits but we defer that trait to - // the 'MoveableTestType'. - - char *d_data_p; - bslma::Allocator *d_allocator_p; - - public: - // CREATORS - explicit TestType(bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numDefaultCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '?'; - } - - explicit TestType(char c, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCharCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = c; - } - - explicit TestType(const TestType& original, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCopyCtorCalls; - if (&original != this) { - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = *original.d_data_p; - } - } - - ~TestType() - { - ++numDestructorCalls; - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = 0; - } - - // MANIPULATORS - TestType& operator=(const TestType& rhs) - { - ++numAssignmentCalls; - if (&rhs != this) { - char *newData = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = newData; - *d_data_p = *rhs.d_data_p; - } - return *this; - } - - void setDatum(char c) - { - *d_data_p = c; - } - - // ACCESSORS - char datum() const - { - return *d_data_p; - } - - void print() const - { - if (d_data_p) { - ASSERT(isalpha(*d_data_p)); - printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); - } else { - printf("VOID\n"); - } - } -}; - -// TRAITS -namespace BloombergLP { -namespace bslma { -template <> struct UsesBslmaAllocator : bsl::true_type {}; -} -} - -bool operator==(const TestType& lhs, const TestType& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ===================== - // class TestTypeNoAlloc - // ===================== - -class TestTypeNoAlloc { - // This test type has footprint and interface identical to 'TestType'. It - // also counts the number of default and copy constructions, assignments, - // and destructions. It does not allocate, and thus could have the - // bit-wise copyable trait, but we defer this to the - // 'BitwiseCopyableTestType'. - - // DATA - union { - char d_char; - char d_fill[sizeof(TestType)]; - bsls::AlignmentFromType::Type d_align; - } d_u; - - public: - // CREATORS - TestTypeNoAlloc() - { - d_u.d_char = '?'; - ++numDefaultCtorCalls; - } - - explicit TestTypeNoAlloc(char c) - { - d_u.d_char = c; - ++numCharCtorCalls; - } - - TestTypeNoAlloc(const TestTypeNoAlloc& original) - { - d_u.d_char = original.d_u.d_char; - ++numCopyCtorCalls; - } - - ~TestTypeNoAlloc() - { - ++numDestructorCalls; - d_u.d_char = '_'; - } - - // MANIPULATORS - TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) - { - ++numAssignmentCalls; - d_u.d_char = rhs.d_u.d_char; - return *this; - } - - // ACCESSORS - char datum() const - { - return d_u.d_char; - } - - void print() const - { - ASSERT(isalpha(d_u.d_char)); - printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); - } -}; - -bool operator==(const TestTypeNoAlloc& lhs, - const TestTypeNoAlloc& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ============================= - // class BitwiseCopyableTestType - // ============================= - -class BitwiseCopyableTestType : public TestTypeNoAlloc { - // This test type is identical to 'TestTypeNoAlloc' except that it has the - // bit-wise copyable trait. All members are inherited. - - public: - // CREATORS - BitwiseCopyableTestType() - : TestTypeNoAlloc() - { - } - - explicit BitwiseCopyableTestType(char c) - : TestTypeNoAlloc(c) - { - ++numCharCtorCalls; - } - - BitwiseCopyableTestType(const BitwiseCopyableTestType& original) - : TestTypeNoAlloc(original.datum()) - { - } -}; - -// TRAITS -namespace bsl { -template <> struct is_trivially_copyable - : true_type {}; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR TESTING -//----------------------------------------------------------------------------- - -template -class CleanupGuard { - // This proctor is responsible to create, in an array specified at - // construction, a sequence according to some specification. Upon - // destruction, it destroys elements in that array according to the current - // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if - // and only if '1 == isalpha(spec[i])' and in addition, if a reference to - // an end pointer is specified at construction, if 'i < *specEnd - spec'. - // If a tests succeeds, the specifications can be changed to allow for - // different (un)initialized elements. - - // DATA - TYPE *d_array_p; - const char *d_spec_p; - TYPE **d_endPtr_p; - TYPE *d_initialEndPtr_p; - int d_length; - - public: - // CREATORS - CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) - : d_array_p(array) - , d_spec_p(spec) - , d_endPtr_p(endPtr) - , d_initialEndPtr_p(endPtr ? *endPtr : 0) - , d_length(strlen(spec)) - { - } - - ~CleanupGuard() - { - for (int i = 0; d_spec_p[i] && i < d_length; ++i) { - char c = d_spec_p[i]; - if (isalpha(c)) { - if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && - i < d_initialEndPtr_p - d_array_p) { - continue; // those elements have already been moved - } - Obj::destroy(d_array_p + i, d_array_p + i + 1); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } - } - - // MANIPULATORS - void setLength(int length) - { - d_length = length; - } - - void release(const char *newSpec) - { - d_spec_p = newSpec; - d_length = strlen(newSpec); - d_endPtr_p = 0; - } -}; - -template -void cleanup(TYPE *array, const char *spec) - // Destroy elements in the specified 'array' according to the specified - // 'spec'. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if and - // only if '1 == isalpha(spec[i])'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP_ASSERT(i, array[i].datum() == c); - Obj::destroy(array + i, array + i + 1); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -template -void verify(TYPE *array, const char *spec) - // Verify that elements in the specified 'array' have values according to - // the specified 'spec'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP3_ASSERT(i, array[i].datum(), c, array[i].datum() == c); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -void fillWithJunk(void *buf, int size) -{ - const int MAX_VALUE = 127; - - char *p = reinterpret_cast(buf); - - for (int i = 0; i < size; ++i) { - p[i] = (i % MAX_VALUE) + 1; - } -} - -//============================================================================= -// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING -//----------------------------------------------------------------------------- -// The following functions interpret the given 'spec' in order from left to -// right to configure an array according to a custom language. Letters -// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to -// initialize elements of an array of 'T' objects. An underscore ('_') -// indicates that an element should be left uninitialized. -// -// LANGUAGE SPECIFICATION -// ---------------------- -// -// ::= | -// -// ::= -// -// ::= | -// -// ::= | -// -// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | -// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | -// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | -// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | -// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | -// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' -// -// ::= '_' -// -// Spec String Description -// ----------- --------------------------------------------------------------- -// "" Leaves the array unaffected. -// "a" ... -//----------------------------------------------------------------------------- - -template -int ggg(TYPE *array, const char *spec, int verboseFlag = 1) - // Configure the specified 'array' of objects of the parameterized 'TYPE' - // (assumed to be uninitialized) according to the specified 'spec'. - // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error - // messages. Return the index of the first invalid character, and a - // negative value otherwise. Note that this function is used to implement - // 'gg' as well as allow for verification of syntax error detection. - // - // Note that this generator is used in exception tests, and thus need to be - // exception-safe. -{ - CleanupGuard guard(array, spec); - guard.setLength(0); - - enum { SUCCESS = -1 }; - for (int i = 0; spec[i]; ++i, ++array) { - char c = spec[i]; - guard.setLength(i); - if (isalpha(c)) { - bslalg::ScalarPrimitives::construct(array, c, Z); - } - else if ('_' == c) { - continue; - } - else { - if (verboseFlag) { - printf("Error, bad character ('%c') in spec \"%s\"" - " at position %d.\n", spec[i], spec, i); - } - - // Discontinue processing this spec. - - return i; // RETURN - } - } - guard.setLength(0); - return SUCCESS; -} - -template -TYPE& gg(TYPE *array, const char *spec) - // Return a reference to the modifiable first element of the specified - // 'array' after the value of 'array' has been adjusted according to the - // specified 'spec'. -{ - ASSERT(ggg(array, spec) < 0); - return *array; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR CASE 2 -//----------------------------------------------------------------------------- - -static const struct { - int d_lineNum; // source line number - const char *d_spec; // specification string - int d_begin; // start of [begin, end) range - int d_ne; // number of elements (ne = end - begin). - const char *d_expected; // expected result array -} DATA_2[] = { - // Order test data by increasing 'ne'. - - //line spec begin ne expected - //---- ---- ----- -- -------- - { L_, "___", 1, 0, "___" }, // 0 - { L_, "_b_", 1, 0, "_b_" }, - { L_, "abc", 1, 0, "abc" }, - - { L_, "_b_", 1, 1, "___" }, // 1 - { L_, "abc", 1, 1, "a_c" }, - - { L_, "_bc_", 1, 2, "____" }, // 2 - { L_, "abcd", 1, 2, "a__d" }, - - { L_, "abcde", 1, 3, "a___e" }, // 3 - - { L_, "abcdef", 1, 4, "a____f" }, // 4 - - { L_, "abcdefg", 1, 5, "a_____g" }, // 5 -}; -const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; - -template -void testDestroy(bool bitwiseCopyableFlag) -{ - const int MAX_SIZE = 16; - static union { - char d_raw[MAX_SIZE * sizeof(T)]; - bsls::AlignmentUtil::MaxAlignedType d_align; - } u; - T *buf = (T*)&u.d_raw[0]; - - for (int ti = 0; ti < NUM_DATA_2; ++ti) { - const int LINE = DATA_2[ti].d_lineNum; - const char *const SPEC = DATA_2[ti].d_spec; - const int BEGIN = DATA_2[ti].d_begin; - const int NE = DATA_2[ti].d_ne; - const char *const EXP = DATA_2[ti].d_expected; - ASSERT(MAX_SIZE >= (int)strlen(SPEC)); - - if (veryVerbose) { - printf("LINE = %d, SPEC = %s, " - "BEGIN = %d, NE = %d, EXP = %s\n", - LINE, SPEC, BEGIN, NE, EXP); - } - gg(buf, SPEC); verify(buf, SPEC); - - const int NUM_DESTRUCTIONS = numDestructorCalls; - - Obj::destroy(&buf[BEGIN], &buf[BEGIN + NE]); - - if (bitwiseCopyableFlag) { - ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); - } - verify(buf, EXP); - cleanup(buf, EXP); - } -} - -// ============================================================================ -// USAGE EXAMPLE -// ---------------------------------------------------------------------------- - -namespace UsageExample { - -///Usage -///----- -// In this section we show intended use of this component. Note that this -// component is for use by the 'bslstl' package. Other clients should use the -// STL algorithms (in header '' and ''). -// -///Example 1: Destroy Arrays of 'int' and 'Integer' Wrapper Objects -/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// In this example, we will use 'bslalg::ArrayDestructionPrimitives' to destroy -// both an array of integer scalars and an array of 'MyInteger' objects. -// Calling the 'destory' method on an array of integers is a no-op while -// calling the 'destroy' method on an array of objects of 'MyInteger' class -// invokes the destructor of each of the objects in the array. -// -// First, we define a 'MyInteger' class that contains an integer value: -//.. - class MyInteger { - // This class represents an integer value. -// - int d_intValue; // integer value -// - public: - // CREATORS - MyInteger(); - // Create a 'MyInteger' object having integer value '0'. -// - explicit MyInteger(int value); - // Create a 'MyInteger' object having the specified 'value'. -// - ~MyInteger(); - // Destroy this object. -// - // ACCESSORS - int getValue() const; - // Return the integer value contained in this object. - }; -//.. - -// CREATORS -MyInteger::MyInteger() -:d_intValue(0) -{ -} - -MyInteger::MyInteger(int value) -:d_intValue(value) -{ -} - -MyInteger::~MyInteger() -{ -} - -// ACCESSORS -int MyInteger::getValue() const -{ - return d_intValue; -} - -} // close namespace UsageExample - -//============================================================================= -// MAIN PROGRAM -//----------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - int test = argc > 1 ? atoi(argv[1]) : 0; - - verbose = argc > 2; - veryVerbose = argc > 3; - veryVeryVerbose = argc > 4; - - setbuf(stdout, NULL); // Use unbuffered output - - printf("TEST " __FILE__ " CASE %d\n", test); - - bslma::TestAllocator testAllocator(veryVeryVerbose); - Z = &testAllocator; - - switch (test) { case 0: // Zero is always the leading case. - case 3: { - // -------------------------------------------------------------------- - // TESTING USAGE EXAMPLE - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting Usage Example" - "\n=====================\n"); - using namespace UsageExample; - -//.. -// Then, we create an array of of objects, 'myIntegers', of type 'MyInteger' -// (note that we 'bsls::ObjectBuffer' to allow us to safely invoke the -// destructor explicitly): -//.. - bsls::ObjectBuffer arrayBuffer[5]; - MyInteger *myIntegers = &arrayBuffer[0].object(); - for (int i = 0;i < 5; ++i) { - new (myIntegers + i) MyInteger(i); - } -//.. -// Now, we define a primitive integer array: -//.. - int scalarIntegers[] = { 0, 1, 2, 3, 4 }; -//.. -// Finally, we use the uniform 'bslalg::ArrayDestructionPrimitives:destroy' -// method to destroy both 'myIntegers' and 'scalarIntegers': -//.. - bslalg::ArrayDestructionPrimitives::destroy(myIntegers, myIntegers + 5); - bslalg::ArrayDestructionPrimitives::destroy(scalarIntegers, - scalarIntegers + 5); -//.. - } break; - case 2: { - // -------------------------------------------------------------------- - // TESTING destroy - // - // Concerns: - //: 1. The 'destroy' acts as a uniform interface to destroy arrays of - //: objects of different types as expected. - // - // Plan: - //: 1. Construct arrays of objects of types that have different type - //: traits declared. Call the 'destroy' method on them and verify - //: they are destroyed as expected. (C-1) - // - // Testing: - // void destroy(T *dstB, T *dstE); - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting 'destroy'\n"); - - if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with TestType.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); - testDestroy(false); - - - if(verbose) printf("\nNegative testing\n"); - { - bsls::AssertFailureHandlerGuard g( - bsls::AssertTest::failTestDriver); - - int * null = 0; - ASSERT_SAFE_PASS(Obj::destroy(null, null)); - int simpleArray[] = { 0, 1, 2, 3, 4 }; - int * begin = simpleArray; - int * end = begin; - ASSERT_SAFE_FAIL(Obj::destroy(null, begin)); - ASSERT_SAFE_FAIL(Obj::destroy(begin, null)); - ASSERT_SAFE_PASS(Obj::destroy(begin, begin)); - - ++begin; ++begin; // Advance begin by two to form an invalid range - ++end; - ASSERT_SAFE_FAIL(Obj::destroy(begin, end)); - ++end; - ASSERT(begin == end); - ASSERT_SAFE_PASS(Obj::destroy(begin, end)); - ++end; - ASSERT_SAFE_PASS(Obj::destroy(begin, end)); - } - } break; - case 1: { - // -------------------------------------------------------------------- - // BREATHING TEST - // - // Concerns: - //: 1. The 'destroy' algorithm works as intended. - // - // Plan: - //: 1. Construct objects in a range and use 'destroy' to destroy - // them. Make sure all memory is deallocated. (C-1) - // - // Testing: - // BREATHING TEST - // -------------------------------------------------------------------- - - if (verbose) printf("\nBREATHING TEST" - "\n==============\n"); - - bslma::TestAllocator ta(veryVerbose); - - numDestructorCalls = 0; - { - const int NUM_OBJECTS = 8; - const T VALUE('a'); - - bsls::ObjectBuffer array[NUM_OBJECTS]; - T *buffer = &array[0].object(); - - for (int i = 0; i < NUM_OBJECTS; ++i) { - bslalg::ScalarPrimitives::copyConstruct(buffer + i, - VALUE, - &ta); - } - - Obj::destroy(buffer, buffer + NUM_OBJECTS); - - ASSERT(NUM_OBJECTS == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - numDestructorCalls = 0; - { - const int NUM_OBJECTS = 8; - const TNA VALUE('a'); - - bsls::ObjectBuffer array[NUM_OBJECTS]; - TNA *buffer = &array[0].object(); - - for (int i = 0; i < NUM_OBJECTS; ++i) { - bslalg::ScalarPrimitives::copyConstruct(buffer + i, - VALUE, - &ta); - } - - Obj::destroy(buffer, buffer + NUM_OBJECTS); - - ASSERT(NUM_OBJECTS == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - { - const int NUM_OBJECTS = 8; - const BCT VALUE('a'); - - bsls::ObjectBuffer array[NUM_OBJECTS]; - BCT *buffer = &array[0].object(); - - for (int i = 0; i < NUM_OBJECTS; ++i) { - bslalg::ScalarPrimitives::copyConstruct(buffer + i, - VALUE, - &ta); - } - - Obj::destroy(buffer, buffer + NUM_OBJECTS); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - } break; - default: { - fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); - testStatus = -1; - } - } - - if (testStatus > 0) { - fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); - } - - return testStatus; -} - -// ---------------------------------------------------------------------------- -// Copyright (C) 2012 Bloomberg L.P. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -// ----------------------------- END-OF-FILE ---------------------------------- + +//============================================================================= +// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING +//----------------------------------------------------------------------------- + +typedef bslalg::ArrayDestructionPrimitives Obj; + +// TYPES +class TestType; +class TestTypeNoAlloc; +class BitwiseCopyableTestType; + +typedef TestType T; // uses 'bslma' allocators +typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators +typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators + +typedef bsls::Types::Int64 Int64; +typedef bsls::Types::Uint64 Uint64; + +// STATIC DATA +static int verbose, veryVerbose, veryVeryVerbose; + +const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; + +static int numDefaultCtorCalls = 0; +static int numCharCtorCalls = 0; +static int numCopyCtorCalls = 0; +static int numAssignmentCalls = 0; +static int numDestructorCalls = 0; + +bslma::TestAllocator *Z; // initialized at the start of main() + + // ============== + // class TestType + // ============== + +class TestType { + // This test type contains a 'char' in some allocated storage. It counts + // the number of default and copy constructions, assignments, and + // destructions. It has no traits other than using a 'bslma' allocator. + // It could have the bit-wise moveable traits but we defer that trait to + // the 'MoveableTestType'. + + char *d_data_p; + bslma::Allocator *d_allocator_p; + + public: + // CREATORS + explicit TestType(bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numDefaultCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '?'; + } + + explicit TestType(char c, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCharCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = c; + } + + explicit TestType(const TestType& original, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCopyCtorCalls; + if (&original != this) { + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = *original.d_data_p; + } + } + + ~TestType() + { + ++numDestructorCalls; + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = 0; + } + + // MANIPULATORS + TestType& operator=(const TestType& rhs) + { + ++numAssignmentCalls; + if (&rhs != this) { + char *newData = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = newData; + *d_data_p = *rhs.d_data_p; + } + return *this; + } + + void setDatum(char c) + { + *d_data_p = c; + } + + // ACCESSORS + char datum() const + { + return *d_data_p; + } + + void print() const + { + if (d_data_p) { + ASSERT(isalpha(*d_data_p)); + printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); + } else { + printf("VOID\n"); + } + } +}; + +// TRAITS +namespace BloombergLP { +namespace bslma { +template <> struct UsesBslmaAllocator : bsl::true_type {}; +} +} + +bool operator==(const TestType& lhs, const TestType& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ===================== + // class TestTypeNoAlloc + // ===================== + +class TestTypeNoAlloc { + // This test type has footprint and interface identical to 'TestType'. It + // also counts the number of default and copy constructions, assignments, + // and destructions. It does not allocate, and thus could have the + // bit-wise copyable trait, but we defer this to the + // 'BitwiseCopyableTestType'. + + // DATA + union { + char d_char; + char d_fill[sizeof(TestType)]; + bsls::AlignmentFromType::Type d_align; + } d_u; + + public: + // CREATORS + TestTypeNoAlloc() + { + d_u.d_char = '?'; + ++numDefaultCtorCalls; + } + + explicit TestTypeNoAlloc(char c) + { + d_u.d_char = c; + ++numCharCtorCalls; + } + + TestTypeNoAlloc(const TestTypeNoAlloc& original) + { + d_u.d_char = original.d_u.d_char; + ++numCopyCtorCalls; + } + + ~TestTypeNoAlloc() + { + ++numDestructorCalls; + d_u.d_char = '_'; + } + + // MANIPULATORS + TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) + { + ++numAssignmentCalls; + d_u.d_char = rhs.d_u.d_char; + return *this; + } + + // ACCESSORS + char datum() const + { + return d_u.d_char; + } + + void print() const + { + ASSERT(isalpha(d_u.d_char)); + printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); + } +}; + +bool operator==(const TestTypeNoAlloc& lhs, + const TestTypeNoAlloc& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ============================= + // class BitwiseCopyableTestType + // ============================= + +class BitwiseCopyableTestType : public TestTypeNoAlloc { + // This test type is identical to 'TestTypeNoAlloc' except that it has the + // bit-wise copyable trait. All members are inherited. + + public: + // CREATORS + BitwiseCopyableTestType() + : TestTypeNoAlloc() + { + } + + explicit BitwiseCopyableTestType(char c) + : TestTypeNoAlloc(c) + { + ++numCharCtorCalls; + } + + BitwiseCopyableTestType(const BitwiseCopyableTestType& original) + : TestTypeNoAlloc(original.datum()) + { + } +}; + +// TRAITS +namespace bsl { +template <> struct is_trivially_copyable + : true_type {}; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR TESTING +//----------------------------------------------------------------------------- + +template +class CleanupGuard { + // This proctor is responsible to create, in an array specified at + // construction, a sequence according to some specification. Upon + // destruction, it destroys elements in that array according to the current + // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if + // and only if '1 == isalpha(spec[i])' and in addition, if a reference to + // an end pointer is specified at construction, if 'i < *specEnd - spec'. + // If a tests succeeds, the specifications can be changed to allow for + // different (un)initialized elements. + + // DATA + TYPE *d_array_p; + const char *d_spec_p; + TYPE **d_endPtr_p; + TYPE *d_initialEndPtr_p; + int d_length; + + public: + // CREATORS + CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) + : d_array_p(array) + , d_spec_p(spec) + , d_endPtr_p(endPtr) + , d_initialEndPtr_p(endPtr ? *endPtr : 0) + , d_length(strlen(spec)) + { + } + + ~CleanupGuard() + { + for (int i = 0; d_spec_p[i] && i < d_length; ++i) { + char c = d_spec_p[i]; + if (isalpha(c)) { + if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && + i < d_initialEndPtr_p - d_array_p) { + continue; // those elements have already been moved + } + Obj::destroy(d_array_p + i, d_array_p + i + 1); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } + } + + // MANIPULATORS + void setLength(int length) + { + d_length = length; + } + + void release(const char *newSpec) + { + d_spec_p = newSpec; + d_length = strlen(newSpec); + d_endPtr_p = 0; + } +}; + +template +void cleanup(TYPE *array, const char *spec) + // Destroy elements in the specified 'array' according to the specified + // 'spec'. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if and + // only if '1 == isalpha(spec[i])'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP_ASSERT(i, array[i].datum() == c); + Obj::destroy(array + i, array + i + 1); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +template +void verify(TYPE *array, const char *spec) + // Verify that elements in the specified 'array' have values according to + // the specified 'spec'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP3_ASSERT(i, array[i].datum(), c, array[i].datum() == c); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +void fillWithJunk(void *buf, int size) +{ + const int MAX_VALUE = 127; + + char *p = reinterpret_cast(buf); + + for (int i = 0; i < size; ++i) { + p[i] = (i % MAX_VALUE) + 1; + } +} + +//============================================================================= +// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING +//----------------------------------------------------------------------------- +// The following functions interpret the given 'spec' in order from left to +// right to configure an array according to a custom language. Letters +// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to +// initialize elements of an array of 'T' objects. An underscore ('_') +// indicates that an element should be left uninitialized. +// +// LANGUAGE SPECIFICATION +// ---------------------- +// +// ::= | +// +// ::= +// +// ::= | +// +// ::= | +// +// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | +// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | +// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | +// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | +// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | +// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' +// +// ::= '_' +// +// Spec String Description +// ----------- --------------------------------------------------------------- +// "" Leaves the array unaffected. +// "a" ... +//----------------------------------------------------------------------------- + +template +int ggg(TYPE *array, const char *spec, int verboseFlag = 1) + // Configure the specified 'array' of objects of the parameterized 'TYPE' + // (assumed to be uninitialized) according to the specified 'spec'. + // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error + // messages. Return the index of the first invalid character, and a + // negative value otherwise. Note that this function is used to implement + // 'gg' as well as allow for verification of syntax error detection. + // + // Note that this generator is used in exception tests, and thus need to be + // exception-safe. +{ + CleanupGuard guard(array, spec); + guard.setLength(0); + + enum { SUCCESS = -1 }; + for (int i = 0; spec[i]; ++i, ++array) { + char c = spec[i]; + guard.setLength(i); + if (isalpha(c)) { + bslalg::ScalarPrimitives::construct(array, c, Z); + } + else if ('_' == c) { + continue; + } + else { + if (verboseFlag) { + printf("Error, bad character ('%c') in spec \"%s\"" + " at position %d.\n", spec[i], spec, i); + } + + // Discontinue processing this spec. + + return i; // RETURN + } + } + guard.setLength(0); + return SUCCESS; +} + +template +TYPE& gg(TYPE *array, const char *spec) + // Return a reference to the modifiable first element of the specified + // 'array' after the value of 'array' has been adjusted according to the + // specified 'spec'. +{ + ASSERT(ggg(array, spec) < 0); + return *array; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR CASE 2 +//----------------------------------------------------------------------------- + +static const struct { + int d_lineNum; // source line number + const char *d_spec; // specification string + int d_begin; // start of [begin, end) range + int d_ne; // number of elements (ne = end - begin). + const char *d_expected; // expected result array +} DATA_2[] = { + // Order test data by increasing 'ne'. + + //line spec begin ne expected + //---- ---- ----- -- -------- + { L_, "___", 1, 0, "___" }, // 0 + { L_, "_b_", 1, 0, "_b_" }, + { L_, "abc", 1, 0, "abc" }, + + { L_, "_b_", 1, 1, "___" }, // 1 + { L_, "abc", 1, 1, "a_c" }, + + { L_, "_bc_", 1, 2, "____" }, // 2 + { L_, "abcd", 1, 2, "a__d" }, + + { L_, "abcde", 1, 3, "a___e" }, // 3 + + { L_, "abcdef", 1, 4, "a____f" }, // 4 + + { L_, "abcdefg", 1, 5, "a_____g" }, // 5 +}; +const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; + +template +void testDestroy(bool bitwiseCopyableFlag) +{ + const int MAX_SIZE = 16; + static union { + char d_raw[MAX_SIZE * sizeof(T)]; + bsls::AlignmentUtil::MaxAlignedType d_align; + } u; + T *buf = (T*)&u.d_raw[0]; + + for (int ti = 0; ti < NUM_DATA_2; ++ti) { + const int LINE = DATA_2[ti].d_lineNum; + const char *const SPEC = DATA_2[ti].d_spec; + const int BEGIN = DATA_2[ti].d_begin; + const int NE = DATA_2[ti].d_ne; + const char *const EXP = DATA_2[ti].d_expected; + ASSERT(MAX_SIZE >= (int)strlen(SPEC)); + + if (veryVerbose) { + printf("LINE = %d, SPEC = %s, " + "BEGIN = %d, NE = %d, EXP = %s\n", + LINE, SPEC, BEGIN, NE, EXP); + } + gg(buf, SPEC); verify(buf, SPEC); + + const int NUM_DESTRUCTIONS = numDestructorCalls; + + Obj::destroy(&buf[BEGIN], &buf[BEGIN + NE]); + + if (bitwiseCopyableFlag) { + ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); + } + verify(buf, EXP); + cleanup(buf, EXP); + } +} + +// ============================================================================ +// USAGE EXAMPLE +// ---------------------------------------------------------------------------- + +namespace UsageExample { + +///Usage +///----- +// In this section we show intended use of this component. Note that this +// component is for use by the 'bslstl' package. Other clients should use the +// STL algorithms (in header '' and ''). +// +///Example 1: Destroy Arrays of 'int' and 'Integer' Wrapper Objects +/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// In this example, we will use 'bslalg::ArrayDestructionPrimitives' to destroy +// both an array of integer scalars and an array of 'MyInteger' objects. +// Calling the 'destory' method on an array of integers is a no-op while +// calling the 'destroy' method on an array of objects of 'MyInteger' class +// invokes the destructor of each of the objects in the array. +// +// First, we define a 'MyInteger' class that contains an integer value: +//.. + class MyInteger { + // This class represents an integer value. +// + int d_intValue; // integer value +// + public: + // CREATORS + MyInteger(); + // Create a 'MyInteger' object having integer value '0'. +// + explicit MyInteger(int value); + // Create a 'MyInteger' object having the specified 'value'. +// + ~MyInteger(); + // Destroy this object. +// + // ACCESSORS + int getValue() const; + // Return the integer value contained in this object. + }; +//.. + +// CREATORS +MyInteger::MyInteger() +:d_intValue(0) +{ +} + +MyInteger::MyInteger(int value) +:d_intValue(value) +{ +} + +MyInteger::~MyInteger() +{ +} + +// ACCESSORS +int MyInteger::getValue() const +{ + return d_intValue; +} + +} // close namespace UsageExample + +//============================================================================= +// MAIN PROGRAM +//----------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + int test = argc > 1 ? atoi(argv[1]) : 0; + + verbose = argc > 2; + veryVerbose = argc > 3; + veryVeryVerbose = argc > 4; + + setbuf(stdout, NULL); // Use unbuffered output + + printf("TEST " __FILE__ " CASE %d\n", test); + + bslma::TestAllocator testAllocator(veryVeryVerbose); + Z = &testAllocator; + + switch (test) { case 0: // Zero is always the leading case. + case 3: { + // -------------------------------------------------------------------- + // TESTING USAGE EXAMPLE + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting Usage Example" + "\n=====================\n"); + using namespace UsageExample; + +//.. +// Then, we create an array of of objects, 'myIntegers', of type 'MyInteger' +// (note that we 'bsls::ObjectBuffer' to allow us to safely invoke the +// destructor explicitly): +//.. + bsls::ObjectBuffer arrayBuffer[5]; + MyInteger *myIntegers = &arrayBuffer[0].object(); + for (int i = 0;i < 5; ++i) { + new (myIntegers + i) MyInteger(i); + } +//.. +// Now, we define a primitive integer array: +//.. + int scalarIntegers[] = { 0, 1, 2, 3, 4 }; +//.. +// Finally, we use the uniform 'bslalg::ArrayDestructionPrimitives:destroy' +// method to destroy both 'myIntegers' and 'scalarIntegers': +//.. + bslalg::ArrayDestructionPrimitives::destroy(myIntegers, myIntegers + 5); + bslalg::ArrayDestructionPrimitives::destroy(scalarIntegers, + scalarIntegers + 5); +//.. + } break; + case 2: { + // -------------------------------------------------------------------- + // TESTING destroy + // + // Concerns: + //: 1. The 'destroy' acts as a uniform interface to destroy arrays of + //: objects of different types as expected. + // + // Plan: + //: 1. Construct arrays of objects of types that have different type + //: traits declared. Call the 'destroy' method on them and verify + //: they are destroyed as expected. (C-1) + // + // Testing: + // void destroy(T *dstB, T *dstE); + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting 'destroy'\n"); + + if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with TestType.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); + testDestroy(false); + + + if(verbose) printf("\nNegative testing\n"); + { + bsls::AssertFailureHandlerGuard g( + bsls::AssertTest::failTestDriver); + + int * null = 0; + ASSERT_SAFE_PASS(Obj::destroy(null, null)); + int simpleArray[] = { 0, 1, 2, 3, 4 }; + int * begin = simpleArray; + int * end = begin; + ASSERT_SAFE_FAIL(Obj::destroy(null, begin)); + ASSERT_SAFE_FAIL(Obj::destroy(begin, null)); + ASSERT_SAFE_PASS(Obj::destroy(begin, begin)); + + ++begin; ++begin; // Advance begin by two to form an invalid range + ++end; + ASSERT_SAFE_FAIL(Obj::destroy(begin, end)); + ++end; + ASSERT(begin == end); + ASSERT_SAFE_PASS(Obj::destroy(begin, end)); + ++end; + ASSERT_SAFE_PASS(Obj::destroy(begin, end)); + } + } break; + case 1: { + // -------------------------------------------------------------------- + // BREATHING TEST + // + // Concerns: + //: 1. The 'destroy' algorithm works as intended. + // + // Plan: + //: 1. Construct objects in a range and use 'destroy' to destroy + // them. Make sure all memory is deallocated. (C-1) + // + // Testing: + // BREATHING TEST + // -------------------------------------------------------------------- + + if (verbose) printf("\nBREATHING TEST" + "\n==============\n"); + + bslma::TestAllocator ta(veryVerbose); + + numDestructorCalls = 0; + { + const int NUM_OBJECTS = 8; + const T VALUE('a'); + + bsls::ObjectBuffer array[NUM_OBJECTS]; + T *buffer = &array[0].object(); + + for (int i = 0; i < NUM_OBJECTS; ++i) { + bslalg::ScalarPrimitives::copyConstruct(buffer + i, + VALUE, + &ta); + } + + Obj::destroy(buffer, buffer + NUM_OBJECTS); + + ASSERT(NUM_OBJECTS == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + numDestructorCalls = 0; + { + const int NUM_OBJECTS = 8; + const TNA VALUE('a'); + + bsls::ObjectBuffer array[NUM_OBJECTS]; + TNA *buffer = &array[0].object(); + + for (int i = 0; i < NUM_OBJECTS; ++i) { + bslalg::ScalarPrimitives::copyConstruct(buffer + i, + VALUE, + &ta); + } + + Obj::destroy(buffer, buffer + NUM_OBJECTS); + + ASSERT(NUM_OBJECTS == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + { + const int NUM_OBJECTS = 8; + const BCT VALUE('a'); + + bsls::ObjectBuffer array[NUM_OBJECTS]; + BCT *buffer = &array[0].object(); + + for (int i = 0; i < NUM_OBJECTS; ++i) { + bslalg::ScalarPrimitives::copyConstruct(buffer + i, + VALUE, + &ta); + } + + Obj::destroy(buffer, buffer + NUM_OBJECTS); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + } break; + default: { + fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); + testStatus = -1; + } + } + + if (testStatus > 0) { + fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); + } + + return testStatus; +} + +// ---------------------------------------------------------------------------- +// Copyright (C) 2012 Bloomberg L.P. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// ----------------------------- END-OF-FILE ---------------------------------- diff --git a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp index 62faac8076..a764ff0086 100644 --- a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp +++ b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp @@ -74,37 +74,26 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } - -//============================================================================= -// STANDARD BDE LOOP-ASSERT TEST MACROS -//----------------------------------------------------------------------------- -// NOTE: This implementation of LOOP_ASSERT macros must use printf since -// cout uses new and must not be called during exception testing. - -#define LOOP_ASSERT(I,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - -#define LOOP2_ASSERT(I,J,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\t"); \ - printf("%s", #J ": "); dbg_print(J); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - -#define LOOP3_ASSERT(I,J,K,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\t"); \ - printf("%s", #J ": "); dbg_print(J); printf("\t"); \ - printf("%s", #K ": "); dbg_print(K); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. -#define P(X) dbg_print(#X " = ", X, "\n") // Print identifier and value. -#define P_(X) dbg_print(#X " = ", X, ", ") // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ putchar('\t'); // Print a tab (w/o newline). +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL HELPER FUNCTIONS FOR TESTING diff --git a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp index cc50319d53..251dfce5e7 100644 --- a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp @@ -1,48 +1,67 @@ -// bslalg_scalardestructionprimitives.t.cpp -*-C++-*- - -#include -#include // for testing only - -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include -#include // for testing only -#include // for testing only - -#include // isalpha() -#include -#include // atoi() -#include // strlen() - -using namespace BloombergLP; - +// bslalg_scalardestructionprimitives.t.cpp -*-C++-*- + +#include +#include // for testing only + +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include +#include // for testing only +#include // for testing only + +#include // isalpha() +#include +#include // atoi() +#include // strlen() + +using namespace BloombergLP; + +//============================================================================= +// TEST PLAN +//----------------------------------------------------------------------------- +// Overview +// -------- +// The component to be tested provides a single algorithm to destroy ranges. +// The main concern (besides that the objects are actually destroyed) is that +// the destructor calls are elided if the basic object type is bit-wise +// copyable. +// +// In order to facilitate the generation of test object instances, we make a +// text object have the value semantics of a 'char', and generate an scalar of +// test objects from a string specification via a generating function +// parameterized by the actual test object type. This lets us reuse the same +// test code for bitwise-copyable/moveable test types as well as those that do +// not have those traits. +//----------------------------------------------------------------------------- +// [ 2] void destroy(T *dst); +//----------------------------------------------------------------------------- +// [ 1] BREATHING TEST + //============================================================================= -// TEST PLAN +// STANDARD BDE ASSERT TEST MACRO //----------------------------------------------------------------------------- -// Overview -// -------- -// The component to be tested provides a single algorithm to destroy ranges. -// The main concern (besides that the objects are actually destroyed) is that -// the destructor calls are elided if the basic object type is bit-wise -// copyable. -// -// In order to facilitate the generation of test object instances, we make a -// text object have the value semantics of a 'char', and generate an scalar of -// test objects from a string specification via a generating function -// parameterized by the actual test object type. This lets us reuse the same -// test code for bitwise-copyable/moveable test types as well as those that do -// not have those traits. -//----------------------------------------------------------------------------- -// [ 2] void destroy(T *dst); -//----------------------------------------------------------------------------- -// [ 1] BREATHING TEST +// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY +// FUNCTIONS, INCLUDING IOSTREAMS. +int testStatus = 0; + +namespace { +void aSsErT(int c, const char *s, int i) +{ + if (c) { + printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); + if (testStatus >= 0 && testStatus <= 100) ++testStatus; +} +} +} // close unnamed namespace +# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } + //============================================================================= // STANDARD BDE TEST DRIVER MACROS //----------------------------------------------------------------------------- @@ -63,778 +82,778 @@ using namespace BloombergLP; #define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. #define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). #define L_ BSLS_BSLTESTUTIL_L_ // current Line number - -//============================================================================= -// SEMI-STANDARD NEGATIVE-TESTING MACROS -//----------------------------------------------------------------------------- -#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) -#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) -#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) -#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) -#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) -#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) - -//============================================================================= -// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING -//----------------------------------------------------------------------------- - -typedef bslalg::ScalarDestructionPrimitives Obj; - -// TYPES -class TestType; -class TestTypeNoAlloc; -class BitwiseCopyableTestType; - -typedef TestType T; // uses 'bslma' allocators -typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators -typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators - -typedef bsls::Types::Int64 Int64; -typedef bsls::Types::Uint64 Uint64; - -// STATIC DATA -static int verbose, veryVerbose, veryVeryVerbose; - -const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; - -static int numDefaultCtorCalls = 0; -static int numCharCtorCalls = 0; -static int numCopyCtorCalls = 0; -static int numAssignmentCalls = 0; -static int numDestructorCalls = 0; - -bslma::TestAllocator *Z; // initialized at the start of main() - - // ============== - // class TestType - // ============== - -class TestType { - // This test type contains a 'char' in some allocated storage. It counts - // the number of default and copy constructions, assignments, and - // destructions. It has no traits other than using a 'bslma' allocator. - // It could have the bit-wise moveable traits but we defer that trait to - // the 'MoveableTestType'. - - char *d_data_p; - bslma::Allocator *d_allocator_p; - - public: - // CREATORS - explicit TestType(bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numDefaultCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '?'; - } - - explicit TestType(char c, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCharCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = c; - } - - explicit TestType(const TestType& original, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCopyCtorCalls; - if (&original != this) { - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = *original.d_data_p; - } - } - - ~TestType() - { - ++numDestructorCalls; - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = 0; - } - - // MANIPULATORS - TestType& operator=(const TestType& rhs) - { - ++numAssignmentCalls; - if (&rhs != this) { - char *newData = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = newData; - *d_data_p = *rhs.d_data_p; - } - return *this; - } - - void setDatum(char c) - { - *d_data_p = c; - } - - // ACCESSORS - char datum() const - { - return *d_data_p; - } - - void print() const - { - if (d_data_p) { - ASSERT(isalpha(*d_data_p)); - printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); - } else { - printf("VOID\n"); - } - } -}; - -// TRAITS -namespace BloombergLP { -namespace bslma { -template <> struct UsesBslmaAllocator : bsl::true_type {}; -} -} - -bool operator==(const TestType& lhs, const TestType& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ===================== - // class TestTypeNoAlloc - // ===================== - -class TestTypeNoAlloc { - // This test type has footprint and interface identical to 'TestType'. It - // also counts the number of default and copy constructions, assignments, - // and destructions. It does not allocate, and thus could have the - // bit-wise copyable trait, but we defer this to the - // 'BitwiseCopyableTestType'. - - // DATA - union { - char d_char; - char d_fill[sizeof(TestType)]; - bsls::AlignmentFromType::Type d_align; - } d_u; - - public: - // CREATORS - explicit TestTypeNoAlloc(bslma::Allocator * = 0) - { - d_u.d_char = '?'; - ++numDefaultCtorCalls; - } - - explicit TestTypeNoAlloc(char c, bslma::Allocator * = 0) - { - d_u.d_char = c; - ++numCharCtorCalls; - } - - explicit - TestTypeNoAlloc(const TestTypeNoAlloc& original, bslma::Allocator * = 0) - { - d_u.d_char = original.d_u.d_char; - ++numCopyCtorCalls; - } - - ~TestTypeNoAlloc() - { - ++numDestructorCalls; - d_u.d_char = '_'; - } - - // MANIPULATORS - TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) - { - ++numAssignmentCalls; - d_u.d_char = rhs.d_u.d_char; - return *this; - } - - // ACCESSORS - char datum() const - { - return d_u.d_char; - } - - void print() const - { - ASSERT(isalpha(d_u.d_char)); - printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); - } -}; - -bool operator==(const TestTypeNoAlloc& lhs, - const TestTypeNoAlloc& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ============================= - // class BitwiseCopyableTestType - // ============================= - -class BitwiseCopyableTestType : public TestTypeNoAlloc { - // This test type is identical to 'TestTypeNoAlloc' except that it has the - // bit-wise copyable trait. All members are inherited. - - public: - // CREATORS - explicit BitwiseCopyableTestType(bslma::Allocator * = 0) - : TestTypeNoAlloc() - { - } - - explicit BitwiseCopyableTestType(char c, bslma::Allocator * = 0) - : TestTypeNoAlloc(c) - { - ++numCharCtorCalls; - } - - explicit BitwiseCopyableTestType(const BitwiseCopyableTestType& original, - bslma::Allocator * = 0) - : TestTypeNoAlloc(original.datum()) - { - } -}; - -namespace bsl { -template <> struct is_trivially_copyable - : true_type {}; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR TESTING -//----------------------------------------------------------------------------- - -template -class CleanupGuard { - // This proctor is responsible to create, in an array specified at - // construction, a sequence according to some specification. Upon - // destruction, it destroys elements in that array according to the current - // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if - // and only if '1 == isalpha(spec[i])' and in addition, if a reference to - // an end pointer is specified at construction, if 'i < *specEnd - spec'. - // If a tests succeeds, the specifications can be changed to allow for - // different (un)initialized elements. - - // DATA - TYPE *d_array_p; - const char *d_spec_p; - TYPE **d_endPtr_p; - TYPE *d_initialEndPtr_p; - int d_length; - - public: - // CREATORS - CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) - : d_array_p(array) - , d_spec_p(spec) - , d_endPtr_p(endPtr) - , d_initialEndPtr_p(endPtr ? *endPtr : 0) - , d_length(strlen(spec)) - { - } - - ~CleanupGuard() - { - for (int i = 0; d_spec_p[i] && i < d_length; ++i) { - char c = d_spec_p[i]; - if (isalpha(c)) { - if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && - i < d_initialEndPtr_p - d_array_p) { - continue; // those elements have already been moved - } - Obj::destroy(d_array_p + i); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } - } - - // MANIPULATORS - void setLength(int length) - { - d_length = length; - } - - void release(const char *newSpec) - { - d_spec_p = newSpec; - d_length = strlen(newSpec); - d_endPtr_p = 0; - } -}; - -template -void cleanup(TYPE *scalar, const char *spec) - // Destroy elements in the specified 'scalar' according to the specified - // 'spec'. For '0 <= i < strlen(spec)', 'scalar[i]' is destroyed if and - // only if '1 == isalpha(spec[i])'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP_ASSERT(i, scalar[i].datum() == c); - Obj::destroy(scalar + i); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -template -void verify(TYPE *scalar, const char *spec) - // Verify that elements in the specified 'scalar' have values according to - // the specified 'spec'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP3_ASSERT(i, scalar[i].datum(), c, scalar[i].datum() == c); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -void fillWithJunk(void *buf, int size) -{ - const int MAX_VALUE = 127; - - char *p = reinterpret_cast(buf); - - for (int i = 0; i < size; ++i) { - p[i] = (i % MAX_VALUE) + 1; - } -} - -//============================================================================= -// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING -//----------------------------------------------------------------------------- -// The following functions interpret the given 'spec' in order from left to -// right to configure an scalar according to a custom language. Letters -// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to -// initialize elements of an scalar of 'T' objects. An underscore ('_') -// indicates that an element should be left uninitialized. -// -// LANGUAGE SPECIFICATION -// ---------------------- -// -// ::= | -// -// ::= -// -// ::= | -// -// ::= | -// -// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | -// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | -// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | -// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | -// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | -// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' -// -// ::= '_' -// -// Spec String Description -// ----------- --------------------------------------------------------------- -// "" Leaves the scalar unaffected. -// "a" ... -//----------------------------------------------------------------------------- - -template -int ggg(TYPE *scalar, const char *spec, int verboseFlag = 1) - // Configure the specified 'scalar' of objects of the parameterized 'TYPE' - // (assumed to be uninitialized) according to the specified 'spec'. - // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error - // messages. Return the index of the first invalid character, and a - // negative value otherwise. Note that this function is used to implement - // 'gg' as well as allow for verification of syntax error detection. - // - // Note that this generator is used in exception tests, and thus need to be - // exception-safe. -{ - CleanupGuard guard(scalar, spec); - guard.setLength(0); - - enum { SUCCESS = -1 }; - for (int i = 0; spec[i]; ++i, ++scalar) { - char c = spec[i]; - guard.setLength(i); - if (isalpha(c)) { - new (scalar) TYPE(c, Z); - } - else if ('_' == c) { - continue; - } - else { - if (verboseFlag) { - printf("Error, bad character ('%c') in spec \"%s\"" - " at position %d.\n", spec[i], spec, i); - } - // Discontinue processing this spec. - return i; // RETURN - } - } - guard.setLength(0); - return SUCCESS; -} - -template -TYPE& gg(TYPE *scalar, const char *spec) - // Return a reference to the modifiable first element of the specified - // 'scalar' after the value of 'scalar' has been adjusted according to the - // specified 'spec'. -{ - ASSERT(ggg(scalar, spec) < 0); - return *scalar; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR CASE 2 -//----------------------------------------------------------------------------- - -static const struct { - int d_lineNum; // source line number - const char *d_spec; // specification string - int d_begin; // start of [begin, end) range - int d_ne; // number of elements (ne = end - begin). - const char *d_expected; // expected result scalar -} DATA_2[] = { - // Order test data by increasing 'ne'. - - //line spec begin ne expected - //---- ---- ----- -- -------- - { L_, "___", 1, 0, "___" }, // 0 - { L_, "_b_", 1, 0, "_b_" }, - { L_, "abc", 1, 0, "abc" }, - - { L_, "_b_", 1, 1, "___" }, // 1 - { L_, "abc", 1, 1, "a_c" }, - - { L_, "_bc_", 1, 2, "____" }, // 2 - { L_, "abcd", 1, 2, "a__d" }, - - { L_, "abcde", 1, 3, "a___e" }, // 3 - - { L_, "abcdef", 1, 4, "a____f" }, // 4 - - { L_, "abcdefg", 1, 5, "a_____g" }, // 5 -}; -const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; - -template -void testDestroy(bool bitwiseCopyableFlag) -{ - const int MAX_SIZE = 16; - static union { - char d_raw[MAX_SIZE * sizeof(T)]; - bsls::AlignmentUtil::MaxAlignedType d_align; - } u; - T *buf = (T*)&u.d_raw[0]; - - for (int ti = 0; ti < NUM_DATA_2; ++ti) { - const int LINE = DATA_2[ti].d_lineNum; - const char *const SPEC = DATA_2[ti].d_spec; - const int BEGIN = DATA_2[ti].d_begin; - const int NE = DATA_2[ti].d_ne; - const char *const EXP = DATA_2[ti].d_expected; - const int SIZE = strlen(SPEC); - ASSERT(SIZE <= MAX_SIZE); - - if (veryVerbose) { - printf("LINE = %d, SPEC = %s, " - "BEGIN = %d, NE = %d, EXP = %s\n", - LINE, SPEC, BEGIN, NE, EXP); - } - gg(buf, SPEC); verify(buf, SPEC); - - const int NUM_DESTRUCTIONS = numDestructorCalls; - - for (int i = 0; i < NE; ++i) { - Obj::destroy(&buf[BEGIN + i]); - } - - if (bitwiseCopyableFlag) { - ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); - } - verify(buf, EXP); - cleanup(buf, EXP); - } -} -// ============================================================================ -// USAGE EXAMPLE -// ---------------------------------------------------------------------------- - -namespace UsageExample { -///Usage -///----- -// In this section we show intended use of this component. Note that this -// component is for use by the 'bslstl' package. Other clients should use the -// STL algorithms (in header '' and ''). -// -///Example 1: Destroy 'int' and an Integer Wrapper -///- - - - - - - - - - - - - - - - - - - - - - - - -// In this example, we will use 'bslalg::ScalarDestructionPrimitives' to -// destroy both a scalar integer and a 'MyInteger' type object. Calling the -// 'destory' method on a scalar integer is a no-op while calling the 'destroy' -// method on an object of 'MyInteger' class invokes the destructor of the -// object. -// -// First, we define a 'MyInteger' class that represents an integer value: -//.. -class MyInteger { - // This class represents an integer value. - - // DATA - int d_intValue; // integer value - - public: - // CREATORS - MyInteger(); - // Create a 'MyInteger' object having integer value '0'. - - explicit MyInteger(int value); - // Create a 'MyInteger' object having the specified 'value'. - - ~MyInteger(); - // Destroy this object. - - // ACCESSORS - int getValue() const; -}; -//.. - -// CREATORS -MyInteger::MyInteger() -:d_intValue(0) -{ -} - -MyInteger::MyInteger(int value) -:d_intValue(value) -{ -} - -MyInteger::~MyInteger() -{ -} - -// ACCESSORS -int MyInteger::getValue() const -{ - return d_intValue; -} - -} // close namespace UsageExample - -//============================================================================= -// MAIN PROGRAM -//----------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - int test = argc > 1 ? atoi(argv[1]) : 0; - - verbose = argc > 2; - veryVerbose = argc > 3; - veryVeryVerbose = argc > 4; - - setbuf(stdout, NULL); // Use unbuffered output - - printf("TEST " __FILE__ " CASE %d\n", test); - - bslma::TestAllocator testAllocator(veryVeryVerbose); - Z = &testAllocator; - - switch (test) { case 0: // Zero is always the leading case. - case 3: { - // -------------------------------------------------------------------- - // TESTING USAGE EXAMPLE - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting Usage Example" - "\n=====================\n"); - using namespace UsageExample; -// Then, we create an object, 'myInteger', of type 'MyInteger': -//.. - bsls::ObjectBuffer buffer; - MyInteger *myInteger = &buffer.object(); - new (myInteger) MyInteger(1); -//.. -// Notice that we use an 'ObjectBuffer' to allow us to safely invoke the -// destructor explicitly. -// -// Now, we define a primitive integer: -//.. - int scalarInteger = 2; -//.. -// Finally, we use the uniform 'bslalg::ScalarDestructionPrimitives:destroy' -// method to destroy both 'myInteger' and 'scalarInteger': -//.. - bslalg::ScalarDestructionPrimitives::destroy(myInteger); - bslalg::ScalarDestructionPrimitives::destroy(&scalarInteger); -//.. - } break; - case 2: { - // -------------------------------------------------------------------- - // TESTING destroy - // - // Concerns: - //: 1. The 'destroy' acts as a uniform interface to destroy objects of - //: different types as expected. - // - // Plan: - //: 1. Construct objects of types that have different type traits - //: declared. Call the 'destroy' method on them and verify they - //: are destroyed as expected. - // - // Testing: - // void destroy(T *dst); - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting 'destroy'\n"); - - if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with TestType.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); - testDestroy(false); - - if(verbose) printf("\nNegative testing\n"); - { - bsls::AssertFailureHandlerGuard g( - bsls::AssertTest::failTestDriver); - - int * null = 0; - ASSERT_SAFE_FAIL(Obj::destroy(null)); - - int x = 0; - ASSERT_SAFE_PASS(Obj::destroy(&x)); - } - } break; - case 1: { - // -------------------------------------------------------------------- - // BREATHING TEST - // - // Concerns: - //: 1. That the basic 'destroy' algorithm works as intended. - // - // Plan: - //: 1. Construct objects in a range and use 'destroy' to destroy - //: them. Make sure all memory is deallocated. - // - // Testing: - // BREATHING TEST - // -------------------------------------------------------------------- - - if (verbose) printf("\nBREATHING TEST" - "\n==============\n"); - - bslma::TestAllocator ta(veryVerbose); - - numDestructorCalls = 0; - { - const T VALUE('a'); - - bsls::ObjectBuffer scalar; - T *buffer = &scalar.object(); - - new (buffer) T(VALUE, &ta); - - Obj::destroy(buffer); - - ASSERT(1 == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - numDestructorCalls = 0; - { - const TNA VALUE('a'); - - bsls::ObjectBuffer scalar; - TNA *buffer = &scalar.object(); - - new (buffer) TNA(VALUE, &ta); - - Obj::destroy(buffer); - - ASSERT(1 == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - numDestructorCalls = 0; - { - const BCT VALUE('a'); - - bsls::ObjectBuffer scalar; - BCT *buffer = &scalar.object(); - - new (buffer) BCT(VALUE, &ta); - - Obj::destroy(buffer); - - ASSERT(0 == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - } break; - default: { - fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); - testStatus = -1; - } - } - - if (testStatus > 0) { - fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); - } - - return testStatus; -} - -// ---------------------------------------------------------------------------- -// Copyright (C) 2012 Bloomberg L.P. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -// ----------------------------- END-OF-FILE ---------------------------------- + +//============================================================================= +// SEMI-STANDARD NEGATIVE-TESTING MACROS +//----------------------------------------------------------------------------- +#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) +#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) +#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) +#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) +#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) +#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) + +//============================================================================= +// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING +//----------------------------------------------------------------------------- + +typedef bslalg::ScalarDestructionPrimitives Obj; + +// TYPES +class TestType; +class TestTypeNoAlloc; +class BitwiseCopyableTestType; + +typedef TestType T; // uses 'bslma' allocators +typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators +typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators + +typedef bsls::Types::Int64 Int64; +typedef bsls::Types::Uint64 Uint64; + +// STATIC DATA +static int verbose, veryVerbose, veryVeryVerbose; + +const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; + +static int numDefaultCtorCalls = 0; +static int numCharCtorCalls = 0; +static int numCopyCtorCalls = 0; +static int numAssignmentCalls = 0; +static int numDestructorCalls = 0; + +bslma::TestAllocator *Z; // initialized at the start of main() + + // ============== + // class TestType + // ============== + +class TestType { + // This test type contains a 'char' in some allocated storage. It counts + // the number of default and copy constructions, assignments, and + // destructions. It has no traits other than using a 'bslma' allocator. + // It could have the bit-wise moveable traits but we defer that trait to + // the 'MoveableTestType'. + + char *d_data_p; + bslma::Allocator *d_allocator_p; + + public: + // CREATORS + explicit TestType(bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numDefaultCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '?'; + } + + explicit TestType(char c, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCharCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = c; + } + + explicit TestType(const TestType& original, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCopyCtorCalls; + if (&original != this) { + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = *original.d_data_p; + } + } + + ~TestType() + { + ++numDestructorCalls; + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = 0; + } + + // MANIPULATORS + TestType& operator=(const TestType& rhs) + { + ++numAssignmentCalls; + if (&rhs != this) { + char *newData = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = newData; + *d_data_p = *rhs.d_data_p; + } + return *this; + } + + void setDatum(char c) + { + *d_data_p = c; + } + + // ACCESSORS + char datum() const + { + return *d_data_p; + } + + void print() const + { + if (d_data_p) { + ASSERT(isalpha(*d_data_p)); + printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); + } else { + printf("VOID\n"); + } + } +}; + +// TRAITS +namespace BloombergLP { +namespace bslma { +template <> struct UsesBslmaAllocator : bsl::true_type {}; +} +} + +bool operator==(const TestType& lhs, const TestType& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ===================== + // class TestTypeNoAlloc + // ===================== + +class TestTypeNoAlloc { + // This test type has footprint and interface identical to 'TestType'. It + // also counts the number of default and copy constructions, assignments, + // and destructions. It does not allocate, and thus could have the + // bit-wise copyable trait, but we defer this to the + // 'BitwiseCopyableTestType'. + + // DATA + union { + char d_char; + char d_fill[sizeof(TestType)]; + bsls::AlignmentFromType::Type d_align; + } d_u; + + public: + // CREATORS + explicit TestTypeNoAlloc(bslma::Allocator * = 0) + { + d_u.d_char = '?'; + ++numDefaultCtorCalls; + } + + explicit TestTypeNoAlloc(char c, bslma::Allocator * = 0) + { + d_u.d_char = c; + ++numCharCtorCalls; + } + + explicit + TestTypeNoAlloc(const TestTypeNoAlloc& original, bslma::Allocator * = 0) + { + d_u.d_char = original.d_u.d_char; + ++numCopyCtorCalls; + } + + ~TestTypeNoAlloc() + { + ++numDestructorCalls; + d_u.d_char = '_'; + } + + // MANIPULATORS + TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) + { + ++numAssignmentCalls; + d_u.d_char = rhs.d_u.d_char; + return *this; + } + + // ACCESSORS + char datum() const + { + return d_u.d_char; + } + + void print() const + { + ASSERT(isalpha(d_u.d_char)); + printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); + } +}; + +bool operator==(const TestTypeNoAlloc& lhs, + const TestTypeNoAlloc& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ============================= + // class BitwiseCopyableTestType + // ============================= + +class BitwiseCopyableTestType : public TestTypeNoAlloc { + // This test type is identical to 'TestTypeNoAlloc' except that it has the + // bit-wise copyable trait. All members are inherited. + + public: + // CREATORS + explicit BitwiseCopyableTestType(bslma::Allocator * = 0) + : TestTypeNoAlloc() + { + } + + explicit BitwiseCopyableTestType(char c, bslma::Allocator * = 0) + : TestTypeNoAlloc(c) + { + ++numCharCtorCalls; + } + + explicit BitwiseCopyableTestType(const BitwiseCopyableTestType& original, + bslma::Allocator * = 0) + : TestTypeNoAlloc(original.datum()) + { + } +}; + +namespace bsl { +template <> struct is_trivially_copyable + : true_type {}; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR TESTING +//----------------------------------------------------------------------------- + +template +class CleanupGuard { + // This proctor is responsible to create, in an array specified at + // construction, a sequence according to some specification. Upon + // destruction, it destroys elements in that array according to the current + // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if + // and only if '1 == isalpha(spec[i])' and in addition, if a reference to + // an end pointer is specified at construction, if 'i < *specEnd - spec'. + // If a tests succeeds, the specifications can be changed to allow for + // different (un)initialized elements. + + // DATA + TYPE *d_array_p; + const char *d_spec_p; + TYPE **d_endPtr_p; + TYPE *d_initialEndPtr_p; + int d_length; + + public: + // CREATORS + CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) + : d_array_p(array) + , d_spec_p(spec) + , d_endPtr_p(endPtr) + , d_initialEndPtr_p(endPtr ? *endPtr : 0) + , d_length(strlen(spec)) + { + } + + ~CleanupGuard() + { + for (int i = 0; d_spec_p[i] && i < d_length; ++i) { + char c = d_spec_p[i]; + if (isalpha(c)) { + if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && + i < d_initialEndPtr_p - d_array_p) { + continue; // those elements have already been moved + } + Obj::destroy(d_array_p + i); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } + } + + // MANIPULATORS + void setLength(int length) + { + d_length = length; + } + + void release(const char *newSpec) + { + d_spec_p = newSpec; + d_length = strlen(newSpec); + d_endPtr_p = 0; + } +}; + +template +void cleanup(TYPE *scalar, const char *spec) + // Destroy elements in the specified 'scalar' according to the specified + // 'spec'. For '0 <= i < strlen(spec)', 'scalar[i]' is destroyed if and + // only if '1 == isalpha(spec[i])'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP_ASSERT(i, scalar[i].datum() == c); + Obj::destroy(scalar + i); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +template +void verify(TYPE *scalar, const char *spec) + // Verify that elements in the specified 'scalar' have values according to + // the specified 'spec'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP3_ASSERT(i, scalar[i].datum(), c, scalar[i].datum() == c); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +void fillWithJunk(void *buf, int size) +{ + const int MAX_VALUE = 127; + + char *p = reinterpret_cast(buf); + + for (int i = 0; i < size; ++i) { + p[i] = (i % MAX_VALUE) + 1; + } +} + +//============================================================================= +// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING +//----------------------------------------------------------------------------- +// The following functions interpret the given 'spec' in order from left to +// right to configure an scalar according to a custom language. Letters +// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to +// initialize elements of an scalar of 'T' objects. An underscore ('_') +// indicates that an element should be left uninitialized. +// +// LANGUAGE SPECIFICATION +// ---------------------- +// +// ::= | +// +// ::= +// +// ::= | +// +// ::= | +// +// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | +// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | +// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | +// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | +// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | +// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' +// +// ::= '_' +// +// Spec String Description +// ----------- --------------------------------------------------------------- +// "" Leaves the scalar unaffected. +// "a" ... +//----------------------------------------------------------------------------- + +template +int ggg(TYPE *scalar, const char *spec, int verboseFlag = 1) + // Configure the specified 'scalar' of objects of the parameterized 'TYPE' + // (assumed to be uninitialized) according to the specified 'spec'. + // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error + // messages. Return the index of the first invalid character, and a + // negative value otherwise. Note that this function is used to implement + // 'gg' as well as allow for verification of syntax error detection. + // + // Note that this generator is used in exception tests, and thus need to be + // exception-safe. +{ + CleanupGuard guard(scalar, spec); + guard.setLength(0); + + enum { SUCCESS = -1 }; + for (int i = 0; spec[i]; ++i, ++scalar) { + char c = spec[i]; + guard.setLength(i); + if (isalpha(c)) { + new (scalar) TYPE(c, Z); + } + else if ('_' == c) { + continue; + } + else { + if (verboseFlag) { + printf("Error, bad character ('%c') in spec \"%s\"" + " at position %d.\n", spec[i], spec, i); + } + // Discontinue processing this spec. + return i; // RETURN + } + } + guard.setLength(0); + return SUCCESS; +} + +template +TYPE& gg(TYPE *scalar, const char *spec) + // Return a reference to the modifiable first element of the specified + // 'scalar' after the value of 'scalar' has been adjusted according to the + // specified 'spec'. +{ + ASSERT(ggg(scalar, spec) < 0); + return *scalar; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR CASE 2 +//----------------------------------------------------------------------------- + +static const struct { + int d_lineNum; // source line number + const char *d_spec; // specification string + int d_begin; // start of [begin, end) range + int d_ne; // number of elements (ne = end - begin). + const char *d_expected; // expected result scalar +} DATA_2[] = { + // Order test data by increasing 'ne'. + + //line spec begin ne expected + //---- ---- ----- -- -------- + { L_, "___", 1, 0, "___" }, // 0 + { L_, "_b_", 1, 0, "_b_" }, + { L_, "abc", 1, 0, "abc" }, + + { L_, "_b_", 1, 1, "___" }, // 1 + { L_, "abc", 1, 1, "a_c" }, + + { L_, "_bc_", 1, 2, "____" }, // 2 + { L_, "abcd", 1, 2, "a__d" }, + + { L_, "abcde", 1, 3, "a___e" }, // 3 + + { L_, "abcdef", 1, 4, "a____f" }, // 4 + + { L_, "abcdefg", 1, 5, "a_____g" }, // 5 +}; +const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; + +template +void testDestroy(bool bitwiseCopyableFlag) +{ + const int MAX_SIZE = 16; + static union { + char d_raw[MAX_SIZE * sizeof(T)]; + bsls::AlignmentUtil::MaxAlignedType d_align; + } u; + T *buf = (T*)&u.d_raw[0]; + + for (int ti = 0; ti < NUM_DATA_2; ++ti) { + const int LINE = DATA_2[ti].d_lineNum; + const char *const SPEC = DATA_2[ti].d_spec; + const int BEGIN = DATA_2[ti].d_begin; + const int NE = DATA_2[ti].d_ne; + const char *const EXP = DATA_2[ti].d_expected; + const int SIZE = strlen(SPEC); + ASSERT(SIZE <= MAX_SIZE); + + if (veryVerbose) { + printf("LINE = %d, SPEC = %s, " + "BEGIN = %d, NE = %d, EXP = %s\n", + LINE, SPEC, BEGIN, NE, EXP); + } + gg(buf, SPEC); verify(buf, SPEC); + + const int NUM_DESTRUCTIONS = numDestructorCalls; + + for (int i = 0; i < NE; ++i) { + Obj::destroy(&buf[BEGIN + i]); + } + + if (bitwiseCopyableFlag) { + ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); + } + verify(buf, EXP); + cleanup(buf, EXP); + } +} +// ============================================================================ +// USAGE EXAMPLE +// ---------------------------------------------------------------------------- + +namespace UsageExample { +///Usage +///----- +// In this section we show intended use of this component. Note that this +// component is for use by the 'bslstl' package. Other clients should use the +// STL algorithms (in header '' and ''). +// +///Example 1: Destroy 'int' and an Integer Wrapper +///- - - - - - - - - - - - - - - - - - - - - - - - +// In this example, we will use 'bslalg::ScalarDestructionPrimitives' to +// destroy both a scalar integer and a 'MyInteger' type object. Calling the +// 'destory' method on a scalar integer is a no-op while calling the 'destroy' +// method on an object of 'MyInteger' class invokes the destructor of the +// object. +// +// First, we define a 'MyInteger' class that represents an integer value: +//.. +class MyInteger { + // This class represents an integer value. + + // DATA + int d_intValue; // integer value + + public: + // CREATORS + MyInteger(); + // Create a 'MyInteger' object having integer value '0'. + + explicit MyInteger(int value); + // Create a 'MyInteger' object having the specified 'value'. + + ~MyInteger(); + // Destroy this object. + + // ACCESSORS + int getValue() const; +}; +//.. + +// CREATORS +MyInteger::MyInteger() +:d_intValue(0) +{ +} + +MyInteger::MyInteger(int value) +:d_intValue(value) +{ +} + +MyInteger::~MyInteger() +{ +} + +// ACCESSORS +int MyInteger::getValue() const +{ + return d_intValue; +} + +} // close namespace UsageExample + +//============================================================================= +// MAIN PROGRAM +//----------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + int test = argc > 1 ? atoi(argv[1]) : 0; + + verbose = argc > 2; + veryVerbose = argc > 3; + veryVeryVerbose = argc > 4; + + setbuf(stdout, NULL); // Use unbuffered output + + printf("TEST " __FILE__ " CASE %d\n", test); + + bslma::TestAllocator testAllocator(veryVeryVerbose); + Z = &testAllocator; + + switch (test) { case 0: // Zero is always the leading case. + case 3: { + // -------------------------------------------------------------------- + // TESTING USAGE EXAMPLE + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting Usage Example" + "\n=====================\n"); + using namespace UsageExample; +// Then, we create an object, 'myInteger', of type 'MyInteger': +//.. + bsls::ObjectBuffer buffer; + MyInteger *myInteger = &buffer.object(); + new (myInteger) MyInteger(1); +//.. +// Notice that we use an 'ObjectBuffer' to allow us to safely invoke the +// destructor explicitly. +// +// Now, we define a primitive integer: +//.. + int scalarInteger = 2; +//.. +// Finally, we use the uniform 'bslalg::ScalarDestructionPrimitives:destroy' +// method to destroy both 'myInteger' and 'scalarInteger': +//.. + bslalg::ScalarDestructionPrimitives::destroy(myInteger); + bslalg::ScalarDestructionPrimitives::destroy(&scalarInteger); +//.. + } break; + case 2: { + // -------------------------------------------------------------------- + // TESTING destroy + // + // Concerns: + //: 1. The 'destroy' acts as a uniform interface to destroy objects of + //: different types as expected. + // + // Plan: + //: 1. Construct objects of types that have different type traits + //: declared. Call the 'destroy' method on them and verify they + //: are destroyed as expected. + // + // Testing: + // void destroy(T *dst); + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting 'destroy'\n"); + + if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with TestType.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); + testDestroy(false); + + if(verbose) printf("\nNegative testing\n"); + { + bsls::AssertFailureHandlerGuard g( + bsls::AssertTest::failTestDriver); + + int * null = 0; + ASSERT_SAFE_FAIL(Obj::destroy(null)); + + int x = 0; + ASSERT_SAFE_PASS(Obj::destroy(&x)); + } + } break; + case 1: { + // -------------------------------------------------------------------- + // BREATHING TEST + // + // Concerns: + //: 1. That the basic 'destroy' algorithm works as intended. + // + // Plan: + //: 1. Construct objects in a range and use 'destroy' to destroy + //: them. Make sure all memory is deallocated. + // + // Testing: + // BREATHING TEST + // -------------------------------------------------------------------- + + if (verbose) printf("\nBREATHING TEST" + "\n==============\n"); + + bslma::TestAllocator ta(veryVerbose); + + numDestructorCalls = 0; + { + const T VALUE('a'); + + bsls::ObjectBuffer scalar; + T *buffer = &scalar.object(); + + new (buffer) T(VALUE, &ta); + + Obj::destroy(buffer); + + ASSERT(1 == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + numDestructorCalls = 0; + { + const TNA VALUE('a'); + + bsls::ObjectBuffer scalar; + TNA *buffer = &scalar.object(); + + new (buffer) TNA(VALUE, &ta); + + Obj::destroy(buffer); + + ASSERT(1 == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + numDestructorCalls = 0; + { + const BCT VALUE('a'); + + bsls::ObjectBuffer scalar; + BCT *buffer = &scalar.object(); + + new (buffer) BCT(VALUE, &ta); + + Obj::destroy(buffer); + + ASSERT(0 == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + } break; + default: { + fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); + testStatus = -1; + } + } + + if (testStatus > 0) { + fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); + } + + return testStatus; +} + +// ---------------------------------------------------------------------------- +// Copyright (C) 2012 Bloomberg L.P. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// ----------------------------- END-OF-FILE ---------------------------------- From 743522f4d6dc1f55eddb7906c637204275f7ebf3 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 8 Jan 2013 19:59:45 -0500 Subject: [PATCH 32/49] substituting inline defined macros with standard macros in header files --- groups/bsl/bsls/bsls_alignedbuffer.t.cpp | 39 ++++++++----- groups/bsl/bsls/bsls_ident.t.cpp | 74 ++++++++++-------------- 2 files changed, 55 insertions(+), 58 deletions(-) diff --git a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp index 93eb416dd7..95674886d3 100644 --- a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp +++ b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp @@ -5,7 +5,7 @@ #include #include #include - +#include #include #include @@ -36,24 +36,37 @@ using namespace std; // FUNCTIONS, INCLUDING IOSTREAMS. static int testStatus = 0; -static void aSsErT(int c, const char *s, int i) { +namespace { +void aSsErT(int c, const char *s, int i) +{ if (c) { printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); if (testStatus >= 0 && testStatus <= 100) ++testStatus; } } -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } -//-------------------------------------------------------------------------- - -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. -#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. -//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ printf("\t"); // Print a tab (w/o newline) +} // close unnamed namespace + +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING diff --git a/groups/bsl/bsls/bsls_ident.t.cpp b/groups/bsl/bsls/bsls_ident.t.cpp index cf4d15bb1f..2b08aee3f4 100644 --- a/groups/bsl/bsls/bsls_ident.t.cpp +++ b/groups/bsl/bsls/bsls_ident.t.cpp @@ -3,11 +3,10 @@ // *** The format of this component test driver is non-standard. *** - +#include // #include // included below in usage example. #include // 'atoi' #include - // using namespace BloombergLP; //============================================================================= @@ -22,56 +21,41 @@ //========================================================================== // STANDARD BDE ASSERT TEST MACRO //-------------------------------------------------------------------------- +// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY +// FUNCTIONS, INCLUDING IOSTREAMS. static int testStatus = 0; -static void aSsErT(int c, const char *s, int i) { +namespace { +void aSsErT(int c, const char *s, int i) +{ if (c) { - std::cout << "Error " << __FILE__ << "(" << i << "): " << s - << " (failed)" << std::endl; + printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); if (testStatus >= 0 && testStatus <= 100) ++testStatus; } } -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } -//-------------------------------------------------------------------------- -#define LOOP_ASSERT(I,X) { \ - if (!(X)) { std::cout << #I << ": " << I << "\n"; \ - aSsErT(1, #X, __LINE__); } } - -#define LOOP2_ASSERT(I,J,X) { \ - if (!(X)) { std::cout << #I << ": " << I << "\t" << #J << ": " \ - << J << "\n"; aSsErT(1, #X, __LINE__); } } - -#define LOOP3_ASSERT(I,J,K,X) { \ - if (!(X)) { std::cout << #I << ": " << I << "\t" << #J << ": " << J \ - << "\t" << #K << ": " << K << "\n"; \ - aSsErT(1, #X, __LINE__); } } - -#define LOOP4_ASSERT(I,J,K,L,X) { \ - if (!(X)) { std::cout << #I << ": " << I << "\t" << #J << ": " << J \ - << "\t" << #K << ": " << K << "\t" << #L << ": " \ - << L << "\n"; aSsErT(1, #X, __LINE__); } } - -#define LOOP5_ASSERT(I,J,K,L,M,X) { \ - if (!(X)) { std::cout << #I << ": " << I << "\t" << #J << ": " << J \ - << "\t" << #K << ": " << K << "\t" << #L << ": " \ - << L << "\t" << #M << ": " << M << "\n"; \ - aSsErT(1, #X, __LINE__); } } - -#define LOOP6_ASSERT(I,J,K,L,M,N,X) { \ - if (!(X)) { std::cout << #I << ": " << I << "\t" << #J << ": " << J \ - << "\t" << #K << ": " << K << "\t" << #L << ": " \ - << L << "\t" << #M << ": " << M << "\t" << #N \ - << ": " << N << "\n"; aSsErT(1, #X, __LINE__); } } - -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -#define P(X) std::cout << #X " = " << (X) << std::endl; // Print ID and value. -#define Q(X) std::cout << "<| " #X " |>" << std::endl; // Quote ID literally. -#define P_(X) std::cout << #X " = " << (X) << ", " << flush; // P(X) w/o '\n' -#define L_ __LINE__ // current Line number -#define T_ std::cout << "\t" << flush; // Print a tab (w/o newline) +} // close unnamed namespace + +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING From 34074a8c014cbf556ec9315aea409fb0224a8a7c Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 00:12:12 -0500 Subject: [PATCH 33/49] add cstdio so it will build --- groups/bsl/bsls/bsls_ident.t.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/groups/bsl/bsls/bsls_ident.t.cpp b/groups/bsl/bsls/bsls_ident.t.cpp index 2b08aee3f4..be140baabf 100644 --- a/groups/bsl/bsls/bsls_ident.t.cpp +++ b/groups/bsl/bsls/bsls_ident.t.cpp @@ -6,6 +6,7 @@ #include // #include // included below in usage example. #include // 'atoi' +#include #include // using namespace BloombergLP; From 3fcadebaa39ac5f2d6342fb9fc0229604a258c9e Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 10:50:31 -0500 Subject: [PATCH 34/49] substituting inline defined macros with standard macros in header files --- groups/bsl/bslstl/bslstl_pair.t.cpp | 42 +++++++++++--------- groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp | 41 ++++++++++++------- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_pair.t.cpp b/groups/bsl/bslstl/bslstl_pair.t.cpp index 3f71ee1c71..9e0055268a 100644 --- a/groups/bsl/bslstl/bslstl_pair.t.cpp +++ b/groups/bsl/bslstl/bslstl_pair.t.cpp @@ -1,6 +1,6 @@ // bslstl_pair.t.cpp -*-C++-*- - #include +#include #include #include @@ -80,30 +80,36 @@ using namespace BloombergLP; static int testStatus = 0; namespace { - // Namespace, because of the error on AIX/xlC: - // "Static declarations are not considered for a function call if the - // function is not qualified." - -void aSsErT(int c, const char *s, int i) { +void aSsErT(int c, const char *s, int i) +{ if (c) { - std::printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); + printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); if (testStatus >= 0 && testStatus <= 100) ++testStatus; } } } // close unnamed namespace -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } -//-------------------------------------------------------------------------- - -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. -#define Q(X) std::printf("<| " #X " |>\n"); // Quote identifier literally. -//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ std::printf("\t"); // Print a tab (w/o newline) +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING diff --git a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp index fa5ff9018b..4687bfa33c 100644 --- a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +++ b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp @@ -1,6 +1,6 @@ // bslstl_stdexceptutil.t.cpp -*-C++-*- #include - +#include #include #include // yes, we want the native std here @@ -41,31 +41,44 @@ using namespace std; // ----------------------------------------------------------------------------- // [ 1] BREATHING TEST // [ 2] USAGE EXAMPLE -// ========================================================================== +//========================================================================== // STANDARD BDE ASSERT TEST MACRO -// -------------------------------------------------------------------------- +//-------------------------------------------------------------------------- // NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY // FUNCTIONS, INCLUDING IOSTREAMS. static int testStatus = 0; -static void aSsErT(int c, const char *s, int i) { +namespace { +void aSsErT(int c, const char *s, int i) +{ if (c) { printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); if (testStatus >= 0 && testStatus <= 100) ++testStatus; } } -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } -//-------------------------------------------------------------------------- +} // close unnamed namespace -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. -#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. -//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ printf("\t"); // Print a tab (w/o newline) +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING From f301b16fb7d28c91c96e37c966e50ad945c016c6 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 11:02:17 -0500 Subject: [PATCH 35/49] substituting inline defined macros with standard macros in header files --- groups/bsl/bslstl/bslstl_pair.t.cpp | 1 + groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/groups/bsl/bslstl/bslstl_pair.t.cpp b/groups/bsl/bslstl/bslstl_pair.t.cpp index 9e0055268a..f61a9e684d 100644 --- a/groups/bsl/bslstl/bslstl_pair.t.cpp +++ b/groups/bsl/bslstl/bslstl_pair.t.cpp @@ -13,6 +13,7 @@ #include #include + #include #include diff --git a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp index 4687bfa33c..7c1b57419e 100644 --- a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +++ b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp @@ -8,6 +8,7 @@ #include #include + using namespace BloombergLP; using namespace std; From 25532623d05c0c2bbb2efcf0f9777923fdfce980 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 11:29:03 -0500 Subject: [PATCH 36/49] substituting inline defined macros with standard macros in header files --- groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index 5651a6d4d4..b12fc0ee80 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -15,7 +15,6 @@ #include // for testing only #include // for testing only - #include #include // atoi() #include // strlen() From b20fd01f6202679c380de8e844c650ec8528c622 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 11:41:46 -0500 Subject: [PATCH 37/49] substituting inline defined macros with standard macros in header files --- .../bslalg_arraydestructionprimitives.t.cpp | 1736 ++++++++--------- 1 file changed, 868 insertions(+), 868 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index b12fc0ee80..5744d9036d 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -1,67 +1,67 @@ -// bslalg_arraydestructionprimitives.t.cpp -*-C++-*- - -#include - -#include // for testing only - -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include -#include // for testing only -#include // for testing only - -#include -#include // atoi() -#include // strlen() -#include // isalpha() - -using namespace BloombergLP; - -//============================================================================= -// TEST PLAN -//----------------------------------------------------------------------------- -// Overview -// -------- -// The component to be tested provides a single algorithm to destroy ranges. -// The main concern (besides that the objects are actually destroyed) is that -// the destructor calls are elided if the basic object type is bit-wise -// copyable. -// -// In order to facilitate the generation of test object instances, we make a -// text object have the value semantics of a 'char', and generate an array of -// test objects from a string specification via a generating function -// parameterized by the actual test object type. This lets us reuse the same -// test code for bitwise-copyable/moveable test types as well as those that do -// not have those traits. -//----------------------------------------------------------------------------- -// bslalg::ArrayPrimitives public interface: -// [ 2] void destroy(T *dstB, T *dstE); -//----------------------------------------------------------------------------- -// [ 1] BREATHING TEST - -//============================================================================= -// STANDARD BDE ASSERT TEST MACRO -//----------------------------------------------------------------------------- -// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY -// FUNCTIONS, INCLUDING IOSTREAMS. -int testStatus = 0; - -namespace { -void aSsErT(int c, const char *s, int i) -{ - if (c) - { - printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); - if (testStatus >= 0 && testStatus <= 100) ++testStatus; - } -} -} // close unnamed namespace - +// bslalg_arraydestructionprimitives.t.cpp -*-C++-*- + +#include + +#include // for testing only + +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only + +#include +#include // atoi() +#include // strlen() +#include // isalpha() + +using namespace BloombergLP; + +//============================================================================= +// TEST PLAN +//----------------------------------------------------------------------------- +// Overview +// -------- +// The component to be tested provides a single algorithm to destroy ranges. +// The main concern (besides that the objects are actually destroyed) is that +// the destructor calls are elided if the basic object type is bit-wise +// copyable. +// +// In order to facilitate the generation of test object instances, we make a +// text object have the value semantics of a 'char', and generate an array of +// test objects from a string specification via a generating function +// parameterized by the actual test object type. This lets us reuse the same +// test code for bitwise-copyable/moveable test types as well as those that do +// not have those traits. +//----------------------------------------------------------------------------- +// bslalg::ArrayPrimitives public interface: +// [ 2] void destroy(T *dstB, T *dstE); +//----------------------------------------------------------------------------- +// [ 1] BREATHING TEST + +//========================================================================== +// STANDARD BDE ASSERT TEST MACRO +//-------------------------------------------------------------------------- +// NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY +// FUNCTIONS, INCLUDING IOSTREAMS. +static int testStatus = 0; + +namespace { +void aSsErT(int c, const char *s, int i) +{ + if (c) { + printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); + if (testStatus >= 0 && testStatus <= 100) ++testStatus; + } +} + +} // close unnamed namespace + //============================================================================= // STANDARD BDE TEST DRIVER MACROS //----------------------------------------------------------------------------- @@ -82,807 +82,807 @@ void aSsErT(int c, const char *s, int i) #define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. #define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). #define L_ BSLS_BSLTESTUTIL_L_ // current Line number - -//============================================================================= -// SEMI-STANDARD NEGATIVE-TESTING MACROS -//----------------------------------------------------------------------------- -#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) -#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) -#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) -#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) -#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) -#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) - -//============================================================================= -// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING -//----------------------------------------------------------------------------- - -typedef bslalg::ArrayDestructionPrimitives Obj; - -// TYPES -class TestType; -class TestTypeNoAlloc; -class BitwiseCopyableTestType; - -typedef TestType T; // uses 'bslma' allocators -typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators -typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators - -typedef bsls::Types::Int64 Int64; -typedef bsls::Types::Uint64 Uint64; - -// STATIC DATA -static int verbose, veryVerbose, veryVeryVerbose; - -const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; - -static int numDefaultCtorCalls = 0; -static int numCharCtorCalls = 0; -static int numCopyCtorCalls = 0; -static int numAssignmentCalls = 0; -static int numDestructorCalls = 0; - -bslma::TestAllocator *Z; // initialized at the start of main() - - // ============== - // class TestType - // ============== - -class TestType { - // This test type contains a 'char' in some allocated storage. It counts - // the number of default and copy constructions, assignments, and - // destructions. It has no traits other than using a 'bslma' allocator. - // It could have the bit-wise moveable traits but we defer that trait to - // the 'MoveableTestType'. - - char *d_data_p; - bslma::Allocator *d_allocator_p; - - public: - // CREATORS - explicit TestType(bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numDefaultCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '?'; - } - - explicit TestType(char c, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCharCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = c; - } - - explicit TestType(const TestType& original, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCopyCtorCalls; - if (&original != this) { - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = *original.d_data_p; - } - } - - ~TestType() - { - ++numDestructorCalls; - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = 0; - } - - // MANIPULATORS - TestType& operator=(const TestType& rhs) - { - ++numAssignmentCalls; - if (&rhs != this) { - char *newData = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = newData; - *d_data_p = *rhs.d_data_p; - } - return *this; - } - - void setDatum(char c) - { - *d_data_p = c; - } - - // ACCESSORS - char datum() const - { - return *d_data_p; - } - - void print() const - { - if (d_data_p) { - ASSERT(isalpha(*d_data_p)); - printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); - } else { - printf("VOID\n"); - } - } -}; - -// TRAITS -namespace BloombergLP { -namespace bslma { -template <> struct UsesBslmaAllocator : bsl::true_type {}; -} -} - -bool operator==(const TestType& lhs, const TestType& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ===================== - // class TestTypeNoAlloc - // ===================== - -class TestTypeNoAlloc { - // This test type has footprint and interface identical to 'TestType'. It - // also counts the number of default and copy constructions, assignments, - // and destructions. It does not allocate, and thus could have the - // bit-wise copyable trait, but we defer this to the - // 'BitwiseCopyableTestType'. - - // DATA - union { - char d_char; - char d_fill[sizeof(TestType)]; - bsls::AlignmentFromType::Type d_align; - } d_u; - - public: - // CREATORS - TestTypeNoAlloc() - { - d_u.d_char = '?'; - ++numDefaultCtorCalls; - } - - explicit TestTypeNoAlloc(char c) - { - d_u.d_char = c; - ++numCharCtorCalls; - } - - TestTypeNoAlloc(const TestTypeNoAlloc& original) - { - d_u.d_char = original.d_u.d_char; - ++numCopyCtorCalls; - } - - ~TestTypeNoAlloc() - { - ++numDestructorCalls; - d_u.d_char = '_'; - } - - // MANIPULATORS - TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) - { - ++numAssignmentCalls; - d_u.d_char = rhs.d_u.d_char; - return *this; - } - - // ACCESSORS - char datum() const - { - return d_u.d_char; - } - - void print() const - { - ASSERT(isalpha(d_u.d_char)); - printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); - } -}; - -bool operator==(const TestTypeNoAlloc& lhs, - const TestTypeNoAlloc& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ============================= - // class BitwiseCopyableTestType - // ============================= - -class BitwiseCopyableTestType : public TestTypeNoAlloc { - // This test type is identical to 'TestTypeNoAlloc' except that it has the - // bit-wise copyable trait. All members are inherited. - - public: - // CREATORS - BitwiseCopyableTestType() - : TestTypeNoAlloc() - { - } - - explicit BitwiseCopyableTestType(char c) - : TestTypeNoAlloc(c) - { - ++numCharCtorCalls; - } - - BitwiseCopyableTestType(const BitwiseCopyableTestType& original) - : TestTypeNoAlloc(original.datum()) - { - } -}; - -// TRAITS -namespace bsl { -template <> struct is_trivially_copyable - : true_type {}; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR TESTING -//----------------------------------------------------------------------------- - -template -class CleanupGuard { - // This proctor is responsible to create, in an array specified at - // construction, a sequence according to some specification. Upon - // destruction, it destroys elements in that array according to the current - // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if - // and only if '1 == isalpha(spec[i])' and in addition, if a reference to - // an end pointer is specified at construction, if 'i < *specEnd - spec'. - // If a tests succeeds, the specifications can be changed to allow for - // different (un)initialized elements. - - // DATA - TYPE *d_array_p; - const char *d_spec_p; - TYPE **d_endPtr_p; - TYPE *d_initialEndPtr_p; - int d_length; - - public: - // CREATORS - CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) - : d_array_p(array) - , d_spec_p(spec) - , d_endPtr_p(endPtr) - , d_initialEndPtr_p(endPtr ? *endPtr : 0) - , d_length(strlen(spec)) - { - } - - ~CleanupGuard() - { - for (int i = 0; d_spec_p[i] && i < d_length; ++i) { - char c = d_spec_p[i]; - if (isalpha(c)) { - if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && - i < d_initialEndPtr_p - d_array_p) { - continue; // those elements have already been moved - } - Obj::destroy(d_array_p + i, d_array_p + i + 1); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } - } - - // MANIPULATORS - void setLength(int length) - { - d_length = length; - } - - void release(const char *newSpec) - { - d_spec_p = newSpec; - d_length = strlen(newSpec); - d_endPtr_p = 0; - } -}; - -template -void cleanup(TYPE *array, const char *spec) - // Destroy elements in the specified 'array' according to the specified - // 'spec'. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if and - // only if '1 == isalpha(spec[i])'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP_ASSERT(i, array[i].datum() == c); - Obj::destroy(array + i, array + i + 1); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -template -void verify(TYPE *array, const char *spec) - // Verify that elements in the specified 'array' have values according to - // the specified 'spec'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP3_ASSERT(i, array[i].datum(), c, array[i].datum() == c); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -void fillWithJunk(void *buf, int size) -{ - const int MAX_VALUE = 127; - - char *p = reinterpret_cast(buf); - - for (int i = 0; i < size; ++i) { - p[i] = (i % MAX_VALUE) + 1; - } -} - -//============================================================================= -// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING -//----------------------------------------------------------------------------- -// The following functions interpret the given 'spec' in order from left to -// right to configure an array according to a custom language. Letters -// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to -// initialize elements of an array of 'T' objects. An underscore ('_') -// indicates that an element should be left uninitialized. -// -// LANGUAGE SPECIFICATION -// ---------------------- -// -// ::= | -// -// ::= -// -// ::= | -// -// ::= | -// -// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | -// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | -// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | -// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | -// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | -// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' -// -// ::= '_' -// -// Spec String Description -// ----------- --------------------------------------------------------------- -// "" Leaves the array unaffected. -// "a" ... -//----------------------------------------------------------------------------- - -template -int ggg(TYPE *array, const char *spec, int verboseFlag = 1) - // Configure the specified 'array' of objects of the parameterized 'TYPE' - // (assumed to be uninitialized) according to the specified 'spec'. - // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error - // messages. Return the index of the first invalid character, and a - // negative value otherwise. Note that this function is used to implement - // 'gg' as well as allow for verification of syntax error detection. - // - // Note that this generator is used in exception tests, and thus need to be - // exception-safe. -{ - CleanupGuard guard(array, spec); - guard.setLength(0); - - enum { SUCCESS = -1 }; - for (int i = 0; spec[i]; ++i, ++array) { - char c = spec[i]; - guard.setLength(i); - if (isalpha(c)) { - bslalg::ScalarPrimitives::construct(array, c, Z); - } - else if ('_' == c) { - continue; - } - else { - if (verboseFlag) { - printf("Error, bad character ('%c') in spec \"%s\"" - " at position %d.\n", spec[i], spec, i); - } - - // Discontinue processing this spec. - - return i; // RETURN - } - } - guard.setLength(0); - return SUCCESS; -} - -template -TYPE& gg(TYPE *array, const char *spec) - // Return a reference to the modifiable first element of the specified - // 'array' after the value of 'array' has been adjusted according to the - // specified 'spec'. -{ - ASSERT(ggg(array, spec) < 0); - return *array; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR CASE 2 -//----------------------------------------------------------------------------- - -static const struct { - int d_lineNum; // source line number - const char *d_spec; // specification string - int d_begin; // start of [begin, end) range - int d_ne; // number of elements (ne = end - begin). - const char *d_expected; // expected result array -} DATA_2[] = { - // Order test data by increasing 'ne'. - - //line spec begin ne expected - //---- ---- ----- -- -------- - { L_, "___", 1, 0, "___" }, // 0 - { L_, "_b_", 1, 0, "_b_" }, - { L_, "abc", 1, 0, "abc" }, - - { L_, "_b_", 1, 1, "___" }, // 1 - { L_, "abc", 1, 1, "a_c" }, - - { L_, "_bc_", 1, 2, "____" }, // 2 - { L_, "abcd", 1, 2, "a__d" }, - - { L_, "abcde", 1, 3, "a___e" }, // 3 - - { L_, "abcdef", 1, 4, "a____f" }, // 4 - - { L_, "abcdefg", 1, 5, "a_____g" }, // 5 -}; -const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; - -template -void testDestroy(bool bitwiseCopyableFlag) -{ - const int MAX_SIZE = 16; - static union { - char d_raw[MAX_SIZE * sizeof(T)]; - bsls::AlignmentUtil::MaxAlignedType d_align; - } u; - T *buf = (T*)&u.d_raw[0]; - - for (int ti = 0; ti < NUM_DATA_2; ++ti) { - const int LINE = DATA_2[ti].d_lineNum; - const char *const SPEC = DATA_2[ti].d_spec; - const int BEGIN = DATA_2[ti].d_begin; - const int NE = DATA_2[ti].d_ne; - const char *const EXP = DATA_2[ti].d_expected; - ASSERT(MAX_SIZE >= (int)strlen(SPEC)); - - if (veryVerbose) { - printf("LINE = %d, SPEC = %s, " - "BEGIN = %d, NE = %d, EXP = %s\n", - LINE, SPEC, BEGIN, NE, EXP); - } - gg(buf, SPEC); verify(buf, SPEC); - - const int NUM_DESTRUCTIONS = numDestructorCalls; - - Obj::destroy(&buf[BEGIN], &buf[BEGIN + NE]); - - if (bitwiseCopyableFlag) { - ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); - } - verify(buf, EXP); - cleanup(buf, EXP); - } -} - -// ============================================================================ -// USAGE EXAMPLE -// ---------------------------------------------------------------------------- - -namespace UsageExample { - -///Usage -///----- -// In this section we show intended use of this component. Note that this -// component is for use by the 'bslstl' package. Other clients should use the -// STL algorithms (in header '' and ''). -// -///Example 1: Destroy Arrays of 'int' and 'Integer' Wrapper Objects -/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// In this example, we will use 'bslalg::ArrayDestructionPrimitives' to destroy -// both an array of integer scalars and an array of 'MyInteger' objects. -// Calling the 'destory' method on an array of integers is a no-op while -// calling the 'destroy' method on an array of objects of 'MyInteger' class -// invokes the destructor of each of the objects in the array. -// -// First, we define a 'MyInteger' class that contains an integer value: -//.. - class MyInteger { - // This class represents an integer value. -// - int d_intValue; // integer value -// - public: - // CREATORS - MyInteger(); - // Create a 'MyInteger' object having integer value '0'. -// - explicit MyInteger(int value); - // Create a 'MyInteger' object having the specified 'value'. -// - ~MyInteger(); - // Destroy this object. -// - // ACCESSORS - int getValue() const; - // Return the integer value contained in this object. - }; -//.. - -// CREATORS -MyInteger::MyInteger() -:d_intValue(0) -{ -} - -MyInteger::MyInteger(int value) -:d_intValue(value) -{ -} - -MyInteger::~MyInteger() -{ -} - -// ACCESSORS -int MyInteger::getValue() const -{ - return d_intValue; -} - -} // close namespace UsageExample - -//============================================================================= -// MAIN PROGRAM -//----------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - int test = argc > 1 ? atoi(argv[1]) : 0; - - verbose = argc > 2; - veryVerbose = argc > 3; - veryVeryVerbose = argc > 4; - - setbuf(stdout, NULL); // Use unbuffered output - - printf("TEST " __FILE__ " CASE %d\n", test); - - bslma::TestAllocator testAllocator(veryVeryVerbose); - Z = &testAllocator; - - switch (test) { case 0: // Zero is always the leading case. - case 3: { - // -------------------------------------------------------------------- - // TESTING USAGE EXAMPLE - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting Usage Example" - "\n=====================\n"); - using namespace UsageExample; - -//.. -// Then, we create an array of of objects, 'myIntegers', of type 'MyInteger' -// (note that we 'bsls::ObjectBuffer' to allow us to safely invoke the -// destructor explicitly): -//.. - bsls::ObjectBuffer arrayBuffer[5]; - MyInteger *myIntegers = &arrayBuffer[0].object(); - for (int i = 0;i < 5; ++i) { - new (myIntegers + i) MyInteger(i); - } -//.. -// Now, we define a primitive integer array: -//.. - int scalarIntegers[] = { 0, 1, 2, 3, 4 }; -//.. -// Finally, we use the uniform 'bslalg::ArrayDestructionPrimitives:destroy' -// method to destroy both 'myIntegers' and 'scalarIntegers': -//.. - bslalg::ArrayDestructionPrimitives::destroy(myIntegers, myIntegers + 5); - bslalg::ArrayDestructionPrimitives::destroy(scalarIntegers, - scalarIntegers + 5); -//.. - } break; - case 2: { - // -------------------------------------------------------------------- - // TESTING destroy - // - // Concerns: - //: 1. The 'destroy' acts as a uniform interface to destroy arrays of - //: objects of different types as expected. - // - // Plan: - //: 1. Construct arrays of objects of types that have different type - //: traits declared. Call the 'destroy' method on them and verify - //: they are destroyed as expected. (C-1) - // - // Testing: - // void destroy(T *dstB, T *dstE); - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting 'destroy'\n"); - - if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with TestType.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); - testDestroy(false); - - - if(verbose) printf("\nNegative testing\n"); - { - bsls::AssertFailureHandlerGuard g( - bsls::AssertTest::failTestDriver); - - int * null = 0; - ASSERT_SAFE_PASS(Obj::destroy(null, null)); - int simpleArray[] = { 0, 1, 2, 3, 4 }; - int * begin = simpleArray; - int * end = begin; - ASSERT_SAFE_FAIL(Obj::destroy(null, begin)); - ASSERT_SAFE_FAIL(Obj::destroy(begin, null)); - ASSERT_SAFE_PASS(Obj::destroy(begin, begin)); - - ++begin; ++begin; // Advance begin by two to form an invalid range - ++end; - ASSERT_SAFE_FAIL(Obj::destroy(begin, end)); - ++end; - ASSERT(begin == end); - ASSERT_SAFE_PASS(Obj::destroy(begin, end)); - ++end; - ASSERT_SAFE_PASS(Obj::destroy(begin, end)); - } - } break; - case 1: { - // -------------------------------------------------------------------- - // BREATHING TEST - // - // Concerns: - //: 1. The 'destroy' algorithm works as intended. - // - // Plan: - //: 1. Construct objects in a range and use 'destroy' to destroy - // them. Make sure all memory is deallocated. (C-1) - // - // Testing: - // BREATHING TEST - // -------------------------------------------------------------------- - - if (verbose) printf("\nBREATHING TEST" - "\n==============\n"); - - bslma::TestAllocator ta(veryVerbose); - - numDestructorCalls = 0; - { - const int NUM_OBJECTS = 8; - const T VALUE('a'); - - bsls::ObjectBuffer array[NUM_OBJECTS]; - T *buffer = &array[0].object(); - - for (int i = 0; i < NUM_OBJECTS; ++i) { - bslalg::ScalarPrimitives::copyConstruct(buffer + i, - VALUE, - &ta); - } - - Obj::destroy(buffer, buffer + NUM_OBJECTS); - - ASSERT(NUM_OBJECTS == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - numDestructorCalls = 0; - { - const int NUM_OBJECTS = 8; - const TNA VALUE('a'); - - bsls::ObjectBuffer array[NUM_OBJECTS]; - TNA *buffer = &array[0].object(); - - for (int i = 0; i < NUM_OBJECTS; ++i) { - bslalg::ScalarPrimitives::copyConstruct(buffer + i, - VALUE, - &ta); - } - - Obj::destroy(buffer, buffer + NUM_OBJECTS); - - ASSERT(NUM_OBJECTS == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - { - const int NUM_OBJECTS = 8; - const BCT VALUE('a'); - - bsls::ObjectBuffer array[NUM_OBJECTS]; - BCT *buffer = &array[0].object(); - - for (int i = 0; i < NUM_OBJECTS; ++i) { - bslalg::ScalarPrimitives::copyConstruct(buffer + i, - VALUE, - &ta); - } - - Obj::destroy(buffer, buffer + NUM_OBJECTS); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - } break; - default: { - fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); - testStatus = -1; - } - } - - if (testStatus > 0) { - fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); - } - - return testStatus; -} - -// ---------------------------------------------------------------------------- -// Copyright (C) 2012 Bloomberg L.P. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -// ----------------------------- END-OF-FILE ---------------------------------- + +//============================================================================= +// SEMI-STANDARD NEGATIVE-TESTING MACROS +//----------------------------------------------------------------------------- +#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) +#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) +#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) +#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) +#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) +#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) + +//============================================================================= +// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING +//----------------------------------------------------------------------------- + +typedef bslalg::ArrayDestructionPrimitives Obj; + +// TYPES +class TestType; +class TestTypeNoAlloc; +class BitwiseCopyableTestType; + +typedef TestType T; // uses 'bslma' allocators +typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators +typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators + +typedef bsls::Types::Int64 Int64; +typedef bsls::Types::Uint64 Uint64; + +// STATIC DATA +static int verbose, veryVerbose, veryVeryVerbose; + +const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; + +static int numDefaultCtorCalls = 0; +static int numCharCtorCalls = 0; +static int numCopyCtorCalls = 0; +static int numAssignmentCalls = 0; +static int numDestructorCalls = 0; + +bslma::TestAllocator *Z; // initialized at the start of main() + + // ============== + // class TestType + // ============== + +class TestType { + // This test type contains a 'char' in some allocated storage. It counts + // the number of default and copy constructions, assignments, and + // destructions. It has no traits other than using a 'bslma' allocator. + // It could have the bit-wise moveable traits but we defer that trait to + // the 'MoveableTestType'. + + char *d_data_p; + bslma::Allocator *d_allocator_p; + + public: + // CREATORS + explicit TestType(bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numDefaultCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '?'; + } + + explicit TestType(char c, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCharCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = c; + } + + explicit TestType(const TestType& original, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCopyCtorCalls; + if (&original != this) { + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = *original.d_data_p; + } + } + + ~TestType() + { + ++numDestructorCalls; + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = 0; + } + + // MANIPULATORS + TestType& operator=(const TestType& rhs) + { + ++numAssignmentCalls; + if (&rhs != this) { + char *newData = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = newData; + *d_data_p = *rhs.d_data_p; + } + return *this; + } + + void setDatum(char c) + { + *d_data_p = c; + } + + // ACCESSORS + char datum() const + { + return *d_data_p; + } + + void print() const + { + if (d_data_p) { + ASSERT(isalpha(*d_data_p)); + printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); + } else { + printf("VOID\n"); + } + } +}; + +// TRAITS +namespace BloombergLP { +namespace bslma { +template <> struct UsesBslmaAllocator : bsl::true_type {}; +} +} + +bool operator==(const TestType& lhs, const TestType& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ===================== + // class TestTypeNoAlloc + // ===================== + +class TestTypeNoAlloc { + // This test type has footprint and interface identical to 'TestType'. It + // also counts the number of default and copy constructions, assignments, + // and destructions. It does not allocate, and thus could have the + // bit-wise copyable trait, but we defer this to the + // 'BitwiseCopyableTestType'. + + // DATA + union { + char d_char; + char d_fill[sizeof(TestType)]; + bsls::AlignmentFromType::Type d_align; + } d_u; + + public: + // CREATORS + TestTypeNoAlloc() + { + d_u.d_char = '?'; + ++numDefaultCtorCalls; + } + + explicit TestTypeNoAlloc(char c) + { + d_u.d_char = c; + ++numCharCtorCalls; + } + + TestTypeNoAlloc(const TestTypeNoAlloc& original) + { + d_u.d_char = original.d_u.d_char; + ++numCopyCtorCalls; + } + + ~TestTypeNoAlloc() + { + ++numDestructorCalls; + d_u.d_char = '_'; + } + + // MANIPULATORS + TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) + { + ++numAssignmentCalls; + d_u.d_char = rhs.d_u.d_char; + return *this; + } + + // ACCESSORS + char datum() const + { + return d_u.d_char; + } + + void print() const + { + ASSERT(isalpha(d_u.d_char)); + printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); + } +}; + +bool operator==(const TestTypeNoAlloc& lhs, + const TestTypeNoAlloc& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ============================= + // class BitwiseCopyableTestType + // ============================= + +class BitwiseCopyableTestType : public TestTypeNoAlloc { + // This test type is identical to 'TestTypeNoAlloc' except that it has the + // bit-wise copyable trait. All members are inherited. + + public: + // CREATORS + BitwiseCopyableTestType() + : TestTypeNoAlloc() + { + } + + explicit BitwiseCopyableTestType(char c) + : TestTypeNoAlloc(c) + { + ++numCharCtorCalls; + } + + BitwiseCopyableTestType(const BitwiseCopyableTestType& original) + : TestTypeNoAlloc(original.datum()) + { + } +}; + +// TRAITS +namespace bsl { +template <> struct is_trivially_copyable + : true_type {}; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR TESTING +//----------------------------------------------------------------------------- + +template +class CleanupGuard { + // This proctor is responsible to create, in an array specified at + // construction, a sequence according to some specification. Upon + // destruction, it destroys elements in that array according to the current + // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if + // and only if '1 == isalpha(spec[i])' and in addition, if a reference to + // an end pointer is specified at construction, if 'i < *specEnd - spec'. + // If a tests succeeds, the specifications can be changed to allow for + // different (un)initialized elements. + + // DATA + TYPE *d_array_p; + const char *d_spec_p; + TYPE **d_endPtr_p; + TYPE *d_initialEndPtr_p; + int d_length; + + public: + // CREATORS + CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) + : d_array_p(array) + , d_spec_p(spec) + , d_endPtr_p(endPtr) + , d_initialEndPtr_p(endPtr ? *endPtr : 0) + , d_length(strlen(spec)) + { + } + + ~CleanupGuard() + { + for (int i = 0; d_spec_p[i] && i < d_length; ++i) { + char c = d_spec_p[i]; + if (isalpha(c)) { + if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && + i < d_initialEndPtr_p - d_array_p) { + continue; // those elements have already been moved + } + Obj::destroy(d_array_p + i, d_array_p + i + 1); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } + } + + // MANIPULATORS + void setLength(int length) + { + d_length = length; + } + + void release(const char *newSpec) + { + d_spec_p = newSpec; + d_length = strlen(newSpec); + d_endPtr_p = 0; + } +}; + +template +void cleanup(TYPE *array, const char *spec) + // Destroy elements in the specified 'array' according to the specified + // 'spec'. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if and + // only if '1 == isalpha(spec[i])'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP_ASSERT(i, array[i].datum() == c); + Obj::destroy(array + i, array + i + 1); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +template +void verify(TYPE *array, const char *spec) + // Verify that elements in the specified 'array' have values according to + // the specified 'spec'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP3_ASSERT(i, array[i].datum(), c, array[i].datum() == c); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +void fillWithJunk(void *buf, int size) +{ + const int MAX_VALUE = 127; + + char *p = reinterpret_cast(buf); + + for (int i = 0; i < size; ++i) { + p[i] = (i % MAX_VALUE) + 1; + } +} + +//============================================================================= +// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING +//----------------------------------------------------------------------------- +// The following functions interpret the given 'spec' in order from left to +// right to configure an array according to a custom language. Letters +// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to +// initialize elements of an array of 'T' objects. An underscore ('_') +// indicates that an element should be left uninitialized. +// +// LANGUAGE SPECIFICATION +// ---------------------- +// +// ::= | +// +// ::= +// +// ::= | +// +// ::= | +// +// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | +// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | +// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | +// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | +// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | +// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' +// +// ::= '_' +// +// Spec String Description +// ----------- --------------------------------------------------------------- +// "" Leaves the array unaffected. +// "a" ... +//----------------------------------------------------------------------------- + +template +int ggg(TYPE *array, const char *spec, int verboseFlag = 1) + // Configure the specified 'array' of objects of the parameterized 'TYPE' + // (assumed to be uninitialized) according to the specified 'spec'. + // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error + // messages. Return the index of the first invalid character, and a + // negative value otherwise. Note that this function is used to implement + // 'gg' as well as allow for verification of syntax error detection. + // + // Note that this generator is used in exception tests, and thus need to be + // exception-safe. +{ + CleanupGuard guard(array, spec); + guard.setLength(0); + + enum { SUCCESS = -1 }; + for (int i = 0; spec[i]; ++i, ++array) { + char c = spec[i]; + guard.setLength(i); + if (isalpha(c)) { + bslalg::ScalarPrimitives::construct(array, c, Z); + } + else if ('_' == c) { + continue; + } + else { + if (verboseFlag) { + printf("Error, bad character ('%c') in spec \"%s\"" + " at position %d.\n", spec[i], spec, i); + } + + // Discontinue processing this spec. + + return i; // RETURN + } + } + guard.setLength(0); + return SUCCESS; +} + +template +TYPE& gg(TYPE *array, const char *spec) + // Return a reference to the modifiable first element of the specified + // 'array' after the value of 'array' has been adjusted according to the + // specified 'spec'. +{ + ASSERT(ggg(array, spec) < 0); + return *array; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR CASE 2 +//----------------------------------------------------------------------------- + +static const struct { + int d_lineNum; // source line number + const char *d_spec; // specification string + int d_begin; // start of [begin, end) range + int d_ne; // number of elements (ne = end - begin). + const char *d_expected; // expected result array +} DATA_2[] = { + // Order test data by increasing 'ne'. + + //line spec begin ne expected + //---- ---- ----- -- -------- + { L_, "___", 1, 0, "___" }, // 0 + { L_, "_b_", 1, 0, "_b_" }, + { L_, "abc", 1, 0, "abc" }, + + { L_, "_b_", 1, 1, "___" }, // 1 + { L_, "abc", 1, 1, "a_c" }, + + { L_, "_bc_", 1, 2, "____" }, // 2 + { L_, "abcd", 1, 2, "a__d" }, + + { L_, "abcde", 1, 3, "a___e" }, // 3 + + { L_, "abcdef", 1, 4, "a____f" }, // 4 + + { L_, "abcdefg", 1, 5, "a_____g" }, // 5 +}; +const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; + +template +void testDestroy(bool bitwiseCopyableFlag) +{ + const int MAX_SIZE = 16; + static union { + char d_raw[MAX_SIZE * sizeof(T)]; + bsls::AlignmentUtil::MaxAlignedType d_align; + } u; + T *buf = (T*)&u.d_raw[0]; + + for (int ti = 0; ti < NUM_DATA_2; ++ti) { + const int LINE = DATA_2[ti].d_lineNum; + const char *const SPEC = DATA_2[ti].d_spec; + const int BEGIN = DATA_2[ti].d_begin; + const int NE = DATA_2[ti].d_ne; + const char *const EXP = DATA_2[ti].d_expected; + ASSERT(MAX_SIZE >= (int)strlen(SPEC)); + + if (veryVerbose) { + printf("LINE = %d, SPEC = %s, " + "BEGIN = %d, NE = %d, EXP = %s\n", + LINE, SPEC, BEGIN, NE, EXP); + } + gg(buf, SPEC); verify(buf, SPEC); + + const int NUM_DESTRUCTIONS = numDestructorCalls; + + Obj::destroy(&buf[BEGIN], &buf[BEGIN + NE]); + + if (bitwiseCopyableFlag) { + ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); + } + verify(buf, EXP); + cleanup(buf, EXP); + } +} + +// ============================================================================ +// USAGE EXAMPLE +// ---------------------------------------------------------------------------- + +namespace UsageExample { + +///Usage +///----- +// In this section we show intended use of this component. Note that this +// component is for use by the 'bslstl' package. Other clients should use the +// STL algorithms (in header '' and ''). +// +///Example 1: Destroy Arrays of 'int' and 'Integer' Wrapper Objects +/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// In this example, we will use 'bslalg::ArrayDestructionPrimitives' to destroy +// both an array of integer scalars and an array of 'MyInteger' objects. +// Calling the 'destory' method on an array of integers is a no-op while +// calling the 'destroy' method on an array of objects of 'MyInteger' class +// invokes the destructor of each of the objects in the array. +// +// First, we define a 'MyInteger' class that contains an integer value: +//.. + class MyInteger { + // This class represents an integer value. +// + int d_intValue; // integer value +// + public: + // CREATORS + MyInteger(); + // Create a 'MyInteger' object having integer value '0'. +// + explicit MyInteger(int value); + // Create a 'MyInteger' object having the specified 'value'. +// + ~MyInteger(); + // Destroy this object. +// + // ACCESSORS + int getValue() const; + // Return the integer value contained in this object. + }; +//.. + +// CREATORS +MyInteger::MyInteger() +:d_intValue(0) +{ +} + +MyInteger::MyInteger(int value) +:d_intValue(value) +{ +} + +MyInteger::~MyInteger() +{ +} + +// ACCESSORS +int MyInteger::getValue() const +{ + return d_intValue; +} + +} // close namespace UsageExample + +//============================================================================= +// MAIN PROGRAM +//----------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + int test = argc > 1 ? atoi(argv[1]) : 0; + + verbose = argc > 2; + veryVerbose = argc > 3; + veryVeryVerbose = argc > 4; + + setbuf(stdout, NULL); // Use unbuffered output + + printf("TEST " __FILE__ " CASE %d\n", test); + + bslma::TestAllocator testAllocator(veryVeryVerbose); + Z = &testAllocator; + + switch (test) { case 0: // Zero is always the leading case. + case 3: { + // -------------------------------------------------------------------- + // TESTING USAGE EXAMPLE + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting Usage Example" + "\n=====================\n"); + using namespace UsageExample; + +//.. +// Then, we create an array of of objects, 'myIntegers', of type 'MyInteger' +// (note that we 'bsls::ObjectBuffer' to allow us to safely invoke the +// destructor explicitly): +//.. + bsls::ObjectBuffer arrayBuffer[5]; + MyInteger *myIntegers = &arrayBuffer[0].object(); + for (int i = 0;i < 5; ++i) { + new (myIntegers + i) MyInteger(i); + } +//.. +// Now, we define a primitive integer array: +//.. + int scalarIntegers[] = { 0, 1, 2, 3, 4 }; +//.. +// Finally, we use the uniform 'bslalg::ArrayDestructionPrimitives:destroy' +// method to destroy both 'myIntegers' and 'scalarIntegers': +//.. + bslalg::ArrayDestructionPrimitives::destroy(myIntegers, myIntegers + 5); + bslalg::ArrayDestructionPrimitives::destroy(scalarIntegers, + scalarIntegers + 5); +//.. + } break; + case 2: { + // -------------------------------------------------------------------- + // TESTING destroy + // + // Concerns: + //: 1. The 'destroy' acts as a uniform interface to destroy arrays of + //: objects of different types as expected. + // + // Plan: + //: 1. Construct arrays of objects of types that have different type + //: traits declared. Call the 'destroy' method on them and verify + //: they are destroyed as expected. (C-1) + // + // Testing: + // void destroy(T *b, T *e, *a); + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting 'destroy'\n"); + + if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with TestType.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); + testDestroy(false); + + + if(verbose) printf("\nNegative testing\n"); + { + bsls::AssertFailureHandlerGuard g( + bsls::AssertTest::failTestDriver); + + int * null = 0; + ASSERT_SAFE_PASS(Obj::destroy(null, null)); + int simpleArray[] = { 0, 1, 2, 3, 4 }; + int * begin = simpleArray; + int * end = begin; + ASSERT_SAFE_FAIL(Obj::destroy(null, begin)); + ASSERT_SAFE_FAIL(Obj::destroy(begin, null)); + ASSERT_SAFE_PASS(Obj::destroy(begin, begin)); + + ++begin; ++begin; // Advance begin by two to form an invalid range + ++end; + ASSERT_SAFE_FAIL(Obj::destroy(begin, end)); + ++end; + ASSERT(begin == end); + ASSERT_SAFE_PASS(Obj::destroy(begin, end)); + ++end; + ASSERT_SAFE_PASS(Obj::destroy(begin, end)); + } + } break; + case 1: { + // -------------------------------------------------------------------- + // BREATHING TEST + // + // Concerns: + //: 1. The 'destroy' algorithm works as intended. + // + // Plan: + //: 1. Construct objects in a range and use 'destroy' to destroy + // them. Make sure all memory is deallocated. (C-1) + // + // Testing: + // This test exercises the component but tests nothing. + // -------------------------------------------------------------------- + + if (verbose) printf("\nBREATHING TEST" + "\n==============\n"); + + bslma::TestAllocator ta(veryVerbose); + + numDestructorCalls = 0; + { + const int NUM_OBJECTS = 8; + const T VALUE('a'); + + bsls::ObjectBuffer array[NUM_OBJECTS]; + T *buffer = &array[0].object(); + + for (int i = 0; i < NUM_OBJECTS; ++i) { + bslalg::ScalarPrimitives::copyConstruct(buffer + i, + VALUE, + &ta); + } + + Obj::destroy(buffer, buffer + NUM_OBJECTS); + + ASSERT(NUM_OBJECTS == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + numDestructorCalls = 0; + { + const int NUM_OBJECTS = 8; + const TNA VALUE('a'); + + bsls::ObjectBuffer array[NUM_OBJECTS]; + TNA *buffer = &array[0].object(); + + for (int i = 0; i < NUM_OBJECTS; ++i) { + bslalg::ScalarPrimitives::copyConstruct(buffer + i, + VALUE, + &ta); + } + + Obj::destroy(buffer, buffer + NUM_OBJECTS); + + ASSERT(NUM_OBJECTS == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + { + const int NUM_OBJECTS = 8; + const BCT VALUE('a'); + + bsls::ObjectBuffer array[NUM_OBJECTS]; + BCT *buffer = &array[0].object(); + + for (int i = 0; i < NUM_OBJECTS; ++i) { + bslalg::ScalarPrimitives::copyConstruct(buffer + i, + VALUE, + &ta); + } + + Obj::destroy(buffer, buffer + NUM_OBJECTS); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + } break; + default: { + fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); + testStatus = -1; + } + } + + if (testStatus > 0) { + fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); + } + + return testStatus; +} + +// ---------------------------------------------------------------------------- +// Copyright (C) 2012 Bloomberg L.P. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// ----------------------------- END-OF-FILE ---------------------------------- From b15a63576506343183f95912afe90f50bb4d0c2c Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 9 Jan 2013 11:44:41 -0500 Subject: [PATCH 38/49] adding only 1 empty line --- .../bslalg_arraydestructionprimitives.t.cpp | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index 5744d9036d..8dde91aec4 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -9,9 +9,9 @@ #include // for testing only #include // for testing only #include // for testing only -#include #include // for testing only #include // for testing only + #include // for testing only #include // for testing only @@ -44,44 +44,53 @@ using namespace BloombergLP; //----------------------------------------------------------------------------- // [ 1] BREATHING TEST -//========================================================================== +//============================================================================= // STANDARD BDE ASSERT TEST MACRO -//-------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY // FUNCTIONS, INCLUDING IOSTREAMS. -static int testStatus = 0; +int testStatus = 0; namespace { void aSsErT(int c, const char *s, int i) { - if (c) { + if (c) + { printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); if (testStatus >= 0 && testStatus <= 100) ++testStatus; } } - } // close unnamed namespace -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } +//============================================================================= +// STANDARD BDE LOOP-ASSERT TEST MACROS +//----------------------------------------------------------------------------- +// NOTE: This implementation of LOOP_ASSERT macros must use printf since +// cout uses new and be called during exception testing. +#define LOOP_ASSERT(I,X) { \ + if (!(X)) { printf("%s: %d\n", #I, I); aSsErT(1, #X, __LINE__); } } + +#define LOOP2_ASSERT(I,J,X) { \ + if (!(X)) { printf("%s: %d\t%s: %d\n", #I, I, #J, J); \ + aSsErT(1, #X, __LINE__); } } + +#define LOOP3_ASSERT(I,J,K,X) { \ + if (!(X)) { printf("%s: %d\t%s: %c\t%s: %c\n", #I, I, #J, J, #K, K); \ + aSsErT(1, #X, __LINE__); } } + +#define LOOP4_ASSERT(I,J,K,L,X) { \ + if (!(X)) { printf("%s: %d\t%s: %d\t%s: %d\t%s: %d\n", \ + #I, I, #J, J, #K, K, #L, L); aSsErT(1, #X, __LINE__); } } + +//============================================================================= +// SEMI-STANDARD TEST OUTPUT MACROS +//----------------------------------------------------------------------------- +// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. +#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. +//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' +#define L_ __LINE__ // current Line number +#define T_ printf("\t"); // Print a tab (w/o newline) //============================================================================= // SEMI-STANDARD NEGATIVE-TESTING MACROS From cb7d941c03499f069dc6bc79e694b64e60aab35b Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 12:24:57 -0500 Subject: [PATCH 39/49] substituting inline defined macros with standard macros in header files --- .../bslalg_arraydestructionprimitives.t.cpp | 60 ++++++++----------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index 8dde91aec4..3db465bb07 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -9,9 +9,9 @@ #include // for testing only #include // for testing only #include // for testing only +#include #include // for testing only #include // for testing only - #include // for testing only #include // for testing only @@ -44,53 +44,45 @@ using namespace BloombergLP; //----------------------------------------------------------------------------- // [ 1] BREATHING TEST -//============================================================================= +//========================================================================== // STANDARD BDE ASSERT TEST MACRO -//----------------------------------------------------------------------------- +//-------------------------------------------------------------------------- // NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY // FUNCTIONS, INCLUDING IOSTREAMS. -int testStatus = 0; +static int testStatus = 0; namespace { void aSsErT(int c, const char *s, int i) { - if (c) - { + if (c) { printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); if (testStatus >= 0 && testStatus <= 100) ++testStatus; } } -} // close unnamed namespace - -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } -//============================================================================= -// STANDARD BDE LOOP-ASSERT TEST MACROS -//----------------------------------------------------------------------------- -// NOTE: This implementation of LOOP_ASSERT macros must use printf since -// cout uses new and be called during exception testing. -#define LOOP_ASSERT(I,X) { \ - if (!(X)) { printf("%s: %d\n", #I, I); aSsErT(1, #X, __LINE__); } } - -#define LOOP2_ASSERT(I,J,X) { \ - if (!(X)) { printf("%s: %d\t%s: %d\n", #I, I, #J, J); \ - aSsErT(1, #X, __LINE__); } } -#define LOOP3_ASSERT(I,J,K,X) { \ - if (!(X)) { printf("%s: %d\t%s: %c\t%s: %c\n", #I, I, #J, J, #K, K); \ - aSsErT(1, #X, __LINE__); } } +} // close unnamed namespace -#define LOOP4_ASSERT(I,J,K,L,X) { \ - if (!(X)) { printf("%s: %d\t%s: %d\t%s: %d\t%s: %d\n", \ - #I, I, #J, J, #K, K, #L, L); aSsErT(1, #X, __LINE__); } } +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number -//============================================================================= -// SEMI-STANDARD TEST OUTPUT MACROS -//----------------------------------------------------------------------------- -// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. -#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. -//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ printf("\t"); // Print a tab (w/o newline) //============================================================================= // SEMI-STANDARD NEGATIVE-TESTING MACROS From 68840282f35fe2ffa13675aa67fb62025101d7ee Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:50:35 -0500 Subject: [PATCH 40/49] remove inserted by dan's visual studio --- .../bslalg_arraydestructionprimitives.t.cpp | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index 3db465bb07..1a240964e3 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -62,26 +62,26 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= From 28f0b76a4bd71ae9babb8d7fece1e74b756cbd6e Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:50:55 -0500 Subject: [PATCH 41/49] remove 's inserted by dan's visual studio --- .../bslalg_scalardestructionprimitives.t.cpp | 1682 ++++++++--------- 1 file changed, 841 insertions(+), 841 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp index 251dfce5e7..5cfd7de7f8 100644 --- a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp @@ -1,48 +1,48 @@ -// bslalg_scalardestructionprimitives.t.cpp -*-C++-*- - -#include -#include // for testing only - -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include // for testing only -#include -#include // for testing only -#include // for testing only - -#include // isalpha() -#include -#include // atoi() -#include // strlen() - -using namespace BloombergLP; - -//============================================================================= -// TEST PLAN -//----------------------------------------------------------------------------- -// Overview -// -------- -// The component to be tested provides a single algorithm to destroy ranges. -// The main concern (besides that the objects are actually destroyed) is that -// the destructor calls are elided if the basic object type is bit-wise -// copyable. -// -// In order to facilitate the generation of test object instances, we make a -// text object have the value semantics of a 'char', and generate an scalar of -// test objects from a string specification via a generating function -// parameterized by the actual test object type. This lets us reuse the same -// test code for bitwise-copyable/moveable test types as well as those that do -// not have those traits. -//----------------------------------------------------------------------------- -// [ 2] void destroy(T *dst); -//----------------------------------------------------------------------------- -// [ 1] BREATHING TEST - +// bslalg_scalardestructionprimitives.t.cpp -*-C++-*- + +#include +#include // for testing only + +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include // for testing only +#include +#include // for testing only +#include // for testing only + +#include // isalpha() +#include +#include // atoi() +#include // strlen() + +using namespace BloombergLP; + +//============================================================================= +// TEST PLAN +//----------------------------------------------------------------------------- +// Overview +// -------- +// The component to be tested provides a single algorithm to destroy ranges. +// The main concern (besides that the objects are actually destroyed) is that +// the destructor calls are elided if the basic object type is bit-wise +// copyable. +// +// In order to facilitate the generation of test object instances, we make a +// text object have the value semantics of a 'char', and generate an scalar of +// test objects from a string specification via a generating function +// parameterized by the actual test object type. This lets us reuse the same +// test code for bitwise-copyable/moveable test types as well as those that do +// not have those traits. +//----------------------------------------------------------------------------- +// [ 2] void destroy(T *dst); +//----------------------------------------------------------------------------- +// [ 1] BREATHING TEST + //============================================================================= // STANDARD BDE ASSERT TEST MACRO //----------------------------------------------------------------------------- @@ -61,799 +61,799 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace # define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } - -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number - -//============================================================================= -// SEMI-STANDARD NEGATIVE-TESTING MACROS -//----------------------------------------------------------------------------- -#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) -#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) -#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) -#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) -#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) -#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) - -//============================================================================= -// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING -//----------------------------------------------------------------------------- - -typedef bslalg::ScalarDestructionPrimitives Obj; - -// TYPES -class TestType; -class TestTypeNoAlloc; -class BitwiseCopyableTestType; - -typedef TestType T; // uses 'bslma' allocators -typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators -typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators - -typedef bsls::Types::Int64 Int64; -typedef bsls::Types::Uint64 Uint64; - -// STATIC DATA -static int verbose, veryVerbose, veryVeryVerbose; - -const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; - -static int numDefaultCtorCalls = 0; -static int numCharCtorCalls = 0; -static int numCopyCtorCalls = 0; -static int numAssignmentCalls = 0; -static int numDestructorCalls = 0; - -bslma::TestAllocator *Z; // initialized at the start of main() - - // ============== - // class TestType - // ============== - -class TestType { - // This test type contains a 'char' in some allocated storage. It counts - // the number of default and copy constructions, assignments, and - // destructions. It has no traits other than using a 'bslma' allocator. - // It could have the bit-wise moveable traits but we defer that trait to - // the 'MoveableTestType'. - - char *d_data_p; - bslma::Allocator *d_allocator_p; - - public: - // CREATORS - explicit TestType(bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numDefaultCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '?'; - } - - explicit TestType(char c, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCharCtorCalls; - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = c; - } - - explicit TestType(const TestType& original, bslma::Allocator *ba = 0) - : d_data_p(0) - , d_allocator_p(bslma::Default::allocator(ba)) - { - ++numCopyCtorCalls; - if (&original != this) { - d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = *original.d_data_p; - } - } - - ~TestType() - { - ++numDestructorCalls; - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = 0; - } - - // MANIPULATORS - TestType& operator=(const TestType& rhs) - { - ++numAssignmentCalls; - if (&rhs != this) { - char *newData = (char *)d_allocator_p->allocate(sizeof(char)); - *d_data_p = '_'; - d_allocator_p->deallocate(d_data_p); - d_data_p = newData; - *d_data_p = *rhs.d_data_p; - } - return *this; - } - - void setDatum(char c) - { - *d_data_p = c; - } - - // ACCESSORS - char datum() const - { - return *d_data_p; - } - - void print() const - { - if (d_data_p) { - ASSERT(isalpha(*d_data_p)); - printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); - } else { - printf("VOID\n"); - } - } -}; - -// TRAITS -namespace BloombergLP { -namespace bslma { -template <> struct UsesBslmaAllocator : bsl::true_type {}; -} -} - -bool operator==(const TestType& lhs, const TestType& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ===================== - // class TestTypeNoAlloc - // ===================== - -class TestTypeNoAlloc { - // This test type has footprint and interface identical to 'TestType'. It - // also counts the number of default and copy constructions, assignments, - // and destructions. It does not allocate, and thus could have the - // bit-wise copyable trait, but we defer this to the - // 'BitwiseCopyableTestType'. - - // DATA - union { - char d_char; - char d_fill[sizeof(TestType)]; - bsls::AlignmentFromType::Type d_align; - } d_u; - - public: - // CREATORS - explicit TestTypeNoAlloc(bslma::Allocator * = 0) - { - d_u.d_char = '?'; - ++numDefaultCtorCalls; - } - - explicit TestTypeNoAlloc(char c, bslma::Allocator * = 0) - { - d_u.d_char = c; - ++numCharCtorCalls; - } - - explicit - TestTypeNoAlloc(const TestTypeNoAlloc& original, bslma::Allocator * = 0) - { - d_u.d_char = original.d_u.d_char; - ++numCopyCtorCalls; - } - - ~TestTypeNoAlloc() - { - ++numDestructorCalls; - d_u.d_char = '_'; - } - - // MANIPULATORS - TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) - { - ++numAssignmentCalls; - d_u.d_char = rhs.d_u.d_char; - return *this; - } - - // ACCESSORS - char datum() const - { - return d_u.d_char; - } - - void print() const - { - ASSERT(isalpha(d_u.d_char)); - printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); - } -}; - -bool operator==(const TestTypeNoAlloc& lhs, - const TestTypeNoAlloc& rhs) -{ - ASSERT(isalpha(lhs.datum())); - ASSERT(isalpha(rhs.datum())); - - return lhs.datum() == rhs.datum(); -} - - // ============================= - // class BitwiseCopyableTestType - // ============================= - -class BitwiseCopyableTestType : public TestTypeNoAlloc { - // This test type is identical to 'TestTypeNoAlloc' except that it has the - // bit-wise copyable trait. All members are inherited. - - public: - // CREATORS - explicit BitwiseCopyableTestType(bslma::Allocator * = 0) - : TestTypeNoAlloc() - { - } - - explicit BitwiseCopyableTestType(char c, bslma::Allocator * = 0) - : TestTypeNoAlloc(c) - { - ++numCharCtorCalls; - } - - explicit BitwiseCopyableTestType(const BitwiseCopyableTestType& original, - bslma::Allocator * = 0) - : TestTypeNoAlloc(original.datum()) - { - } -}; - -namespace bsl { -template <> struct is_trivially_copyable - : true_type {}; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR TESTING -//----------------------------------------------------------------------------- - -template -class CleanupGuard { - // This proctor is responsible to create, in an array specified at - // construction, a sequence according to some specification. Upon - // destruction, it destroys elements in that array according to the current - // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if - // and only if '1 == isalpha(spec[i])' and in addition, if a reference to - // an end pointer is specified at construction, if 'i < *specEnd - spec'. - // If a tests succeeds, the specifications can be changed to allow for - // different (un)initialized elements. - - // DATA - TYPE *d_array_p; - const char *d_spec_p; - TYPE **d_endPtr_p; - TYPE *d_initialEndPtr_p; - int d_length; - - public: - // CREATORS - CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) - : d_array_p(array) - , d_spec_p(spec) - , d_endPtr_p(endPtr) - , d_initialEndPtr_p(endPtr ? *endPtr : 0) - , d_length(strlen(spec)) - { - } - - ~CleanupGuard() - { - for (int i = 0; d_spec_p[i] && i < d_length; ++i) { - char c = d_spec_p[i]; - if (isalpha(c)) { - if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && - i < d_initialEndPtr_p - d_array_p) { - continue; // those elements have already been moved - } - Obj::destroy(d_array_p + i); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } - } - - // MANIPULATORS - void setLength(int length) - { - d_length = length; - } - - void release(const char *newSpec) - { - d_spec_p = newSpec; - d_length = strlen(newSpec); - d_endPtr_p = 0; - } -}; - -template -void cleanup(TYPE *scalar, const char *spec) - // Destroy elements in the specified 'scalar' according to the specified - // 'spec'. For '0 <= i < strlen(spec)', 'scalar[i]' is destroyed if and - // only if '1 == isalpha(spec[i])'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP_ASSERT(i, scalar[i].datum() == c); - Obj::destroy(scalar + i); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -template -void verify(TYPE *scalar, const char *spec) - // Verify that elements in the specified 'scalar' have values according to - // the specified 'spec'. -{ - for (int i = 0; spec[i]; ++i) { - char c = spec[i]; - if (isalpha(c)) { - LOOP3_ASSERT(i, scalar[i].datum(), c, scalar[i].datum() == c); - } - else { - LOOP_ASSERT(i, '_' == c); - } - } -} - -void fillWithJunk(void *buf, int size) -{ - const int MAX_VALUE = 127; - - char *p = reinterpret_cast(buf); - - for (int i = 0; i < size; ++i) { - p[i] = (i % MAX_VALUE) + 1; - } -} - -//============================================================================= -// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING -//----------------------------------------------------------------------------- -// The following functions interpret the given 'spec' in order from left to -// right to configure an scalar according to a custom language. Letters -// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to -// initialize elements of an scalar of 'T' objects. An underscore ('_') -// indicates that an element should be left uninitialized. -// -// LANGUAGE SPECIFICATION -// ---------------------- -// -// ::= | -// -// ::= -// -// ::= | -// -// ::= | -// -// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | -// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | -// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | -// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | -// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | -// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' -// -// ::= '_' -// -// Spec String Description -// ----------- --------------------------------------------------------------- -// "" Leaves the scalar unaffected. -// "a" ... -//----------------------------------------------------------------------------- - -template -int ggg(TYPE *scalar, const char *spec, int verboseFlag = 1) - // Configure the specified 'scalar' of objects of the parameterized 'TYPE' - // (assumed to be uninitialized) according to the specified 'spec'. - // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error - // messages. Return the index of the first invalid character, and a - // negative value otherwise. Note that this function is used to implement - // 'gg' as well as allow for verification of syntax error detection. - // - // Note that this generator is used in exception tests, and thus need to be - // exception-safe. -{ - CleanupGuard guard(scalar, spec); - guard.setLength(0); - - enum { SUCCESS = -1 }; - for (int i = 0; spec[i]; ++i, ++scalar) { - char c = spec[i]; - guard.setLength(i); - if (isalpha(c)) { - new (scalar) TYPE(c, Z); - } - else if ('_' == c) { - continue; - } - else { - if (verboseFlag) { - printf("Error, bad character ('%c') in spec \"%s\"" - " at position %d.\n", spec[i], spec, i); - } - // Discontinue processing this spec. - return i; // RETURN - } - } - guard.setLength(0); - return SUCCESS; -} - -template -TYPE& gg(TYPE *scalar, const char *spec) - // Return a reference to the modifiable first element of the specified - // 'scalar' after the value of 'scalar' has been adjusted according to the - // specified 'spec'. -{ - ASSERT(ggg(scalar, spec) < 0); - return *scalar; -} - -//============================================================================= -// GLOBAL HELPER FUNCTIONS FOR CASE 2 -//----------------------------------------------------------------------------- - -static const struct { - int d_lineNum; // source line number - const char *d_spec; // specification string - int d_begin; // start of [begin, end) range - int d_ne; // number of elements (ne = end - begin). - const char *d_expected; // expected result scalar -} DATA_2[] = { - // Order test data by increasing 'ne'. - - //line spec begin ne expected - //---- ---- ----- -- -------- - { L_, "___", 1, 0, "___" }, // 0 - { L_, "_b_", 1, 0, "_b_" }, - { L_, "abc", 1, 0, "abc" }, - - { L_, "_b_", 1, 1, "___" }, // 1 - { L_, "abc", 1, 1, "a_c" }, - - { L_, "_bc_", 1, 2, "____" }, // 2 - { L_, "abcd", 1, 2, "a__d" }, - - { L_, "abcde", 1, 3, "a___e" }, // 3 - - { L_, "abcdef", 1, 4, "a____f" }, // 4 - - { L_, "abcdefg", 1, 5, "a_____g" }, // 5 -}; -const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; - -template -void testDestroy(bool bitwiseCopyableFlag) -{ - const int MAX_SIZE = 16; - static union { - char d_raw[MAX_SIZE * sizeof(T)]; - bsls::AlignmentUtil::MaxAlignedType d_align; - } u; - T *buf = (T*)&u.d_raw[0]; - - for (int ti = 0; ti < NUM_DATA_2; ++ti) { - const int LINE = DATA_2[ti].d_lineNum; - const char *const SPEC = DATA_2[ti].d_spec; - const int BEGIN = DATA_2[ti].d_begin; - const int NE = DATA_2[ti].d_ne; - const char *const EXP = DATA_2[ti].d_expected; - const int SIZE = strlen(SPEC); - ASSERT(SIZE <= MAX_SIZE); - - if (veryVerbose) { - printf("LINE = %d, SPEC = %s, " - "BEGIN = %d, NE = %d, EXP = %s\n", - LINE, SPEC, BEGIN, NE, EXP); - } - gg(buf, SPEC); verify(buf, SPEC); - - const int NUM_DESTRUCTIONS = numDestructorCalls; - - for (int i = 0; i < NE; ++i) { - Obj::destroy(&buf[BEGIN + i]); - } - - if (bitwiseCopyableFlag) { - ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); - } - verify(buf, EXP); - cleanup(buf, EXP); - } -} -// ============================================================================ -// USAGE EXAMPLE -// ---------------------------------------------------------------------------- - -namespace UsageExample { -///Usage -///----- -// In this section we show intended use of this component. Note that this -// component is for use by the 'bslstl' package. Other clients should use the -// STL algorithms (in header '' and ''). -// -///Example 1: Destroy 'int' and an Integer Wrapper -///- - - - - - - - - - - - - - - - - - - - - - - - -// In this example, we will use 'bslalg::ScalarDestructionPrimitives' to -// destroy both a scalar integer and a 'MyInteger' type object. Calling the -// 'destory' method on a scalar integer is a no-op while calling the 'destroy' -// method on an object of 'MyInteger' class invokes the destructor of the -// object. -// -// First, we define a 'MyInteger' class that represents an integer value: -//.. -class MyInteger { - // This class represents an integer value. - - // DATA - int d_intValue; // integer value - - public: - // CREATORS - MyInteger(); - // Create a 'MyInteger' object having integer value '0'. - - explicit MyInteger(int value); - // Create a 'MyInteger' object having the specified 'value'. - - ~MyInteger(); - // Destroy this object. - - // ACCESSORS - int getValue() const; -}; -//.. - -// CREATORS -MyInteger::MyInteger() -:d_intValue(0) -{ -} - -MyInteger::MyInteger(int value) -:d_intValue(value) -{ -} - -MyInteger::~MyInteger() -{ -} - -// ACCESSORS -int MyInteger::getValue() const -{ - return d_intValue; -} - -} // close namespace UsageExample - -//============================================================================= -// MAIN PROGRAM -//----------------------------------------------------------------------------- - -int main(int argc, char *argv[]) -{ - int test = argc > 1 ? atoi(argv[1]) : 0; - - verbose = argc > 2; - veryVerbose = argc > 3; - veryVeryVerbose = argc > 4; - - setbuf(stdout, NULL); // Use unbuffered output - - printf("TEST " __FILE__ " CASE %d\n", test); - - bslma::TestAllocator testAllocator(veryVeryVerbose); - Z = &testAllocator; - - switch (test) { case 0: // Zero is always the leading case. - case 3: { - // -------------------------------------------------------------------- - // TESTING USAGE EXAMPLE - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting Usage Example" - "\n=====================\n"); - using namespace UsageExample; -// Then, we create an object, 'myInteger', of type 'MyInteger': -//.. - bsls::ObjectBuffer buffer; - MyInteger *myInteger = &buffer.object(); - new (myInteger) MyInteger(1); -//.. -// Notice that we use an 'ObjectBuffer' to allow us to safely invoke the -// destructor explicitly. -// -// Now, we define a primitive integer: -//.. - int scalarInteger = 2; -//.. -// Finally, we use the uniform 'bslalg::ScalarDestructionPrimitives:destroy' -// method to destroy both 'myInteger' and 'scalarInteger': -//.. - bslalg::ScalarDestructionPrimitives::destroy(myInteger); - bslalg::ScalarDestructionPrimitives::destroy(&scalarInteger); -//.. - } break; - case 2: { - // -------------------------------------------------------------------- - // TESTING destroy - // - // Concerns: - //: 1. The 'destroy' acts as a uniform interface to destroy objects of - //: different types as expected. - // - // Plan: - //: 1. Construct objects of types that have different type traits - //: declared. Call the 'destroy' method on them and verify they - //: are destroyed as expected. - // - // Testing: - // void destroy(T *dst); - // -------------------------------------------------------------------- - - if (verbose) printf("\nTesting 'destroy'\n"); - - if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with TestType.\n"); - testDestroy(false); - - if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); - testDestroy(false); - - if(verbose) printf("\nNegative testing\n"); - { - bsls::AssertFailureHandlerGuard g( - bsls::AssertTest::failTestDriver); - - int * null = 0; - ASSERT_SAFE_FAIL(Obj::destroy(null)); - - int x = 0; - ASSERT_SAFE_PASS(Obj::destroy(&x)); - } - } break; - case 1: { - // -------------------------------------------------------------------- - // BREATHING TEST - // - // Concerns: - //: 1. That the basic 'destroy' algorithm works as intended. - // - // Plan: - //: 1. Construct objects in a range and use 'destroy' to destroy - //: them. Make sure all memory is deallocated. - // - // Testing: - // BREATHING TEST - // -------------------------------------------------------------------- - - if (verbose) printf("\nBREATHING TEST" - "\n==============\n"); - - bslma::TestAllocator ta(veryVerbose); - - numDestructorCalls = 0; - { - const T VALUE('a'); - - bsls::ObjectBuffer scalar; - T *buffer = &scalar.object(); - - new (buffer) T(VALUE, &ta); - - Obj::destroy(buffer); - - ASSERT(1 == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - numDestructorCalls = 0; - { - const TNA VALUE('a'); - - bsls::ObjectBuffer scalar; - TNA *buffer = &scalar.object(); - - new (buffer) TNA(VALUE, &ta); - - Obj::destroy(buffer); - - ASSERT(1 == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - numDestructorCalls = 0; - { - const BCT VALUE('a'); - - bsls::ObjectBuffer scalar; - BCT *buffer = &scalar.object(); - - new (buffer) BCT(VALUE, &ta); - - Obj::destroy(buffer); - - ASSERT(0 == numDestructorCalls); - } - ASSERT(0 == ta.numMismatches()); - ASSERT(0 == ta.numBytesInUse()); - - } break; - default: { - fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); - testStatus = -1; - } - } - - if (testStatus > 0) { - fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); - } - - return testStatus; -} - -// ---------------------------------------------------------------------------- -// Copyright (C) 2012 Bloomberg L.P. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -// ----------------------------- END-OF-FILE ---------------------------------- + +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number + +//============================================================================= +// SEMI-STANDARD NEGATIVE-TESTING MACROS +//----------------------------------------------------------------------------- +#define ASSERT_SAFE_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_PASS(EXPR) +#define ASSERT_SAFE_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_SAFE_FAIL(EXPR) +#define ASSERT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_PASS(EXPR) +#define ASSERT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_FAIL(EXPR) +#define ASSERT_OPT_PASS(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_PASS(EXPR) +#define ASSERT_OPT_FAIL(EXPR) BSLS_ASSERTTEST_ASSERT_OPT_FAIL(EXPR) + +//============================================================================= +// GLOBAL TYPEDEFS/CONSTANTS/TYPES FOR TESTING +//----------------------------------------------------------------------------- + +typedef bslalg::ScalarDestructionPrimitives Obj; + +// TYPES +class TestType; +class TestTypeNoAlloc; +class BitwiseCopyableTestType; + +typedef TestType T; // uses 'bslma' allocators +typedef TestTypeNoAlloc TNA; // does not use 'bslma' allocators +typedef BitwiseCopyableTestType BCT; // does not use 'bslma' allocators + +typedef bsls::Types::Int64 Int64; +typedef bsls::Types::Uint64 Uint64; + +// STATIC DATA +static int verbose, veryVerbose, veryVeryVerbose; + +const int MAX_ALIGN = bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT; + +static int numDefaultCtorCalls = 0; +static int numCharCtorCalls = 0; +static int numCopyCtorCalls = 0; +static int numAssignmentCalls = 0; +static int numDestructorCalls = 0; + +bslma::TestAllocator *Z; // initialized at the start of main() + + // ============== + // class TestType + // ============== + +class TestType { + // This test type contains a 'char' in some allocated storage. It counts + // the number of default and copy constructions, assignments, and + // destructions. It has no traits other than using a 'bslma' allocator. + // It could have the bit-wise moveable traits but we defer that trait to + // the 'MoveableTestType'. + + char *d_data_p; + bslma::Allocator *d_allocator_p; + + public: + // CREATORS + explicit TestType(bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numDefaultCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '?'; + } + + explicit TestType(char c, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCharCtorCalls; + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = c; + } + + explicit TestType(const TestType& original, bslma::Allocator *ba = 0) + : d_data_p(0) + , d_allocator_p(bslma::Default::allocator(ba)) + { + ++numCopyCtorCalls; + if (&original != this) { + d_data_p = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = *original.d_data_p; + } + } + + ~TestType() + { + ++numDestructorCalls; + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = 0; + } + + // MANIPULATORS + TestType& operator=(const TestType& rhs) + { + ++numAssignmentCalls; + if (&rhs != this) { + char *newData = (char *)d_allocator_p->allocate(sizeof(char)); + *d_data_p = '_'; + d_allocator_p->deallocate(d_data_p); + d_data_p = newData; + *d_data_p = *rhs.d_data_p; + } + return *this; + } + + void setDatum(char c) + { + *d_data_p = c; + } + + // ACCESSORS + char datum() const + { + return *d_data_p; + } + + void print() const + { + if (d_data_p) { + ASSERT(isalpha(*d_data_p)); + printf("%c (int: %d)\n", *d_data_p, (int)*d_data_p); + } else { + printf("VOID\n"); + } + } +}; + +// TRAITS +namespace BloombergLP { +namespace bslma { +template <> struct UsesBslmaAllocator : bsl::true_type {}; +} +} + +bool operator==(const TestType& lhs, const TestType& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ===================== + // class TestTypeNoAlloc + // ===================== + +class TestTypeNoAlloc { + // This test type has footprint and interface identical to 'TestType'. It + // also counts the number of default and copy constructions, assignments, + // and destructions. It does not allocate, and thus could have the + // bit-wise copyable trait, but we defer this to the + // 'BitwiseCopyableTestType'. + + // DATA + union { + char d_char; + char d_fill[sizeof(TestType)]; + bsls::AlignmentFromType::Type d_align; + } d_u; + + public: + // CREATORS + explicit TestTypeNoAlloc(bslma::Allocator * = 0) + { + d_u.d_char = '?'; + ++numDefaultCtorCalls; + } + + explicit TestTypeNoAlloc(char c, bslma::Allocator * = 0) + { + d_u.d_char = c; + ++numCharCtorCalls; + } + + explicit + TestTypeNoAlloc(const TestTypeNoAlloc& original, bslma::Allocator * = 0) + { + d_u.d_char = original.d_u.d_char; + ++numCopyCtorCalls; + } + + ~TestTypeNoAlloc() + { + ++numDestructorCalls; + d_u.d_char = '_'; + } + + // MANIPULATORS + TestTypeNoAlloc& operator=(const TestTypeNoAlloc& rhs) + { + ++numAssignmentCalls; + d_u.d_char = rhs.d_u.d_char; + return *this; + } + + // ACCESSORS + char datum() const + { + return d_u.d_char; + } + + void print() const + { + ASSERT(isalpha(d_u.d_char)); + printf("%c (int: %d)\n", d_u.d_char, (int)d_u.d_char); + } +}; + +bool operator==(const TestTypeNoAlloc& lhs, + const TestTypeNoAlloc& rhs) +{ + ASSERT(isalpha(lhs.datum())); + ASSERT(isalpha(rhs.datum())); + + return lhs.datum() == rhs.datum(); +} + + // ============================= + // class BitwiseCopyableTestType + // ============================= + +class BitwiseCopyableTestType : public TestTypeNoAlloc { + // This test type is identical to 'TestTypeNoAlloc' except that it has the + // bit-wise copyable trait. All members are inherited. + + public: + // CREATORS + explicit BitwiseCopyableTestType(bslma::Allocator * = 0) + : TestTypeNoAlloc() + { + } + + explicit BitwiseCopyableTestType(char c, bslma::Allocator * = 0) + : TestTypeNoAlloc(c) + { + ++numCharCtorCalls; + } + + explicit BitwiseCopyableTestType(const BitwiseCopyableTestType& original, + bslma::Allocator * = 0) + : TestTypeNoAlloc(original.datum()) + { + } +}; + +namespace bsl { +template <> struct is_trivially_copyable + : true_type {}; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR TESTING +//----------------------------------------------------------------------------- + +template +class CleanupGuard { + // This proctor is responsible to create, in an array specified at + // construction, a sequence according to some specification. Upon + // destruction, it destroys elements in that array according to the current + // specifications. For '0 <= i < strlen(spec)', 'array[i]' is destroyed if + // and only if '1 == isalpha(spec[i])' and in addition, if a reference to + // an end pointer is specified at construction, if 'i < *specEnd - spec'. + // If a tests succeeds, the specifications can be changed to allow for + // different (un)initialized elements. + + // DATA + TYPE *d_array_p; + const char *d_spec_p; + TYPE **d_endPtr_p; + TYPE *d_initialEndPtr_p; + int d_length; + + public: + // CREATORS + CleanupGuard(TYPE *array, const char *spec, TYPE**endPtr = 0) + : d_array_p(array) + , d_spec_p(spec) + , d_endPtr_p(endPtr) + , d_initialEndPtr_p(endPtr ? *endPtr : 0) + , d_length(strlen(spec)) + { + } + + ~CleanupGuard() + { + for (int i = 0; d_spec_p[i] && i < d_length; ++i) { + char c = d_spec_p[i]; + if (isalpha(c)) { + if (d_endPtr_p && *d_endPtr_p - d_array_p <= i && + i < d_initialEndPtr_p - d_array_p) { + continue; // those elements have already been moved + } + Obj::destroy(d_array_p + i); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } + } + + // MANIPULATORS + void setLength(int length) + { + d_length = length; + } + + void release(const char *newSpec) + { + d_spec_p = newSpec; + d_length = strlen(newSpec); + d_endPtr_p = 0; + } +}; + +template +void cleanup(TYPE *scalar, const char *spec) + // Destroy elements in the specified 'scalar' according to the specified + // 'spec'. For '0 <= i < strlen(spec)', 'scalar[i]' is destroyed if and + // only if '1 == isalpha(spec[i])'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP_ASSERT(i, scalar[i].datum() == c); + Obj::destroy(scalar + i); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +template +void verify(TYPE *scalar, const char *spec) + // Verify that elements in the specified 'scalar' have values according to + // the specified 'spec'. +{ + for (int i = 0; spec[i]; ++i) { + char c = spec[i]; + if (isalpha(c)) { + LOOP3_ASSERT(i, scalar[i].datum(), c, scalar[i].datum() == c); + } + else { + LOOP_ASSERT(i, '_' == c); + } + } +} + +void fillWithJunk(void *buf, int size) +{ + const int MAX_VALUE = 127; + + char *p = reinterpret_cast(buf); + + for (int i = 0; i < size; ++i) { + p[i] = (i % MAX_VALUE) + 1; + } +} + +//============================================================================= +// GENERATOR FUNCTIONS 'gg' AND 'ggg' FOR TESTING +//----------------------------------------------------------------------------- +// The following functions interpret the given 'spec' in order from left to +// right to configure an scalar according to a custom language. Letters +// [a .. z, A .. Z] correspond to arbitrary (but unique) char values used to +// initialize elements of an scalar of 'T' objects. An underscore ('_') +// indicates that an element should be left uninitialized. +// +// LANGUAGE SPECIFICATION +// ---------------------- +// +// ::= | +// +// ::= +// +// ::= | +// +// ::= | +// +// ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | +// 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | +// 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | +// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | +// 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | +// 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' +// +// ::= '_' +// +// Spec String Description +// ----------- --------------------------------------------------------------- +// "" Leaves the scalar unaffected. +// "a" ... +//----------------------------------------------------------------------------- + +template +int ggg(TYPE *scalar, const char *spec, int verboseFlag = 1) + // Configure the specified 'scalar' of objects of the parameterized 'TYPE' + // (assumed to be uninitialized) according to the specified 'spec'. + // Optionally specify a zero 'verboseFlag' to suppress 'spec' syntax error + // messages. Return the index of the first invalid character, and a + // negative value otherwise. Note that this function is used to implement + // 'gg' as well as allow for verification of syntax error detection. + // + // Note that this generator is used in exception tests, and thus need to be + // exception-safe. +{ + CleanupGuard guard(scalar, spec); + guard.setLength(0); + + enum { SUCCESS = -1 }; + for (int i = 0; spec[i]; ++i, ++scalar) { + char c = spec[i]; + guard.setLength(i); + if (isalpha(c)) { + new (scalar) TYPE(c, Z); + } + else if ('_' == c) { + continue; + } + else { + if (verboseFlag) { + printf("Error, bad character ('%c') in spec \"%s\"" + " at position %d.\n", spec[i], spec, i); + } + // Discontinue processing this spec. + return i; // RETURN + } + } + guard.setLength(0); + return SUCCESS; +} + +template +TYPE& gg(TYPE *scalar, const char *spec) + // Return a reference to the modifiable first element of the specified + // 'scalar' after the value of 'scalar' has been adjusted according to the + // specified 'spec'. +{ + ASSERT(ggg(scalar, spec) < 0); + return *scalar; +} + +//============================================================================= +// GLOBAL HELPER FUNCTIONS FOR CASE 2 +//----------------------------------------------------------------------------- + +static const struct { + int d_lineNum; // source line number + const char *d_spec; // specification string + int d_begin; // start of [begin, end) range + int d_ne; // number of elements (ne = end - begin). + const char *d_expected; // expected result scalar +} DATA_2[] = { + // Order test data by increasing 'ne'. + + //line spec begin ne expected + //---- ---- ----- -- -------- + { L_, "___", 1, 0, "___" }, // 0 + { L_, "_b_", 1, 0, "_b_" }, + { L_, "abc", 1, 0, "abc" }, + + { L_, "_b_", 1, 1, "___" }, // 1 + { L_, "abc", 1, 1, "a_c" }, + + { L_, "_bc_", 1, 2, "____" }, // 2 + { L_, "abcd", 1, 2, "a__d" }, + + { L_, "abcde", 1, 3, "a___e" }, // 3 + + { L_, "abcdef", 1, 4, "a____f" }, // 4 + + { L_, "abcdefg", 1, 5, "a_____g" }, // 5 +}; +const int NUM_DATA_2 = sizeof DATA_2 / sizeof *DATA_2; + +template +void testDestroy(bool bitwiseCopyableFlag) +{ + const int MAX_SIZE = 16; + static union { + char d_raw[MAX_SIZE * sizeof(T)]; + bsls::AlignmentUtil::MaxAlignedType d_align; + } u; + T *buf = (T*)&u.d_raw[0]; + + for (int ti = 0; ti < NUM_DATA_2; ++ti) { + const int LINE = DATA_2[ti].d_lineNum; + const char *const SPEC = DATA_2[ti].d_spec; + const int BEGIN = DATA_2[ti].d_begin; + const int NE = DATA_2[ti].d_ne; + const char *const EXP = DATA_2[ti].d_expected; + const int SIZE = strlen(SPEC); + ASSERT(SIZE <= MAX_SIZE); + + if (veryVerbose) { + printf("LINE = %d, SPEC = %s, " + "BEGIN = %d, NE = %d, EXP = %s\n", + LINE, SPEC, BEGIN, NE, EXP); + } + gg(buf, SPEC); verify(buf, SPEC); + + const int NUM_DESTRUCTIONS = numDestructorCalls; + + for (int i = 0; i < NE; ++i) { + Obj::destroy(&buf[BEGIN + i]); + } + + if (bitwiseCopyableFlag) { + ASSERT(NUM_DESTRUCTIONS == numDestructorCalls); + } + verify(buf, EXP); + cleanup(buf, EXP); + } +} +// ============================================================================ +// USAGE EXAMPLE +// ---------------------------------------------------------------------------- + +namespace UsageExample { +///Usage +///----- +// In this section we show intended use of this component. Note that this +// component is for use by the 'bslstl' package. Other clients should use the +// STL algorithms (in header '' and ''). +// +///Example 1: Destroy 'int' and an Integer Wrapper +///- - - - - - - - - - - - - - - - - - - - - - - - +// In this example, we will use 'bslalg::ScalarDestructionPrimitives' to +// destroy both a scalar integer and a 'MyInteger' type object. Calling the +// 'destory' method on a scalar integer is a no-op while calling the 'destroy' +// method on an object of 'MyInteger' class invokes the destructor of the +// object. +// +// First, we define a 'MyInteger' class that represents an integer value: +//.. +class MyInteger { + // This class represents an integer value. + + // DATA + int d_intValue; // integer value + + public: + // CREATORS + MyInteger(); + // Create a 'MyInteger' object having integer value '0'. + + explicit MyInteger(int value); + // Create a 'MyInteger' object having the specified 'value'. + + ~MyInteger(); + // Destroy this object. + + // ACCESSORS + int getValue() const; +}; +//.. + +// CREATORS +MyInteger::MyInteger() +:d_intValue(0) +{ +} + +MyInteger::MyInteger(int value) +:d_intValue(value) +{ +} + +MyInteger::~MyInteger() +{ +} + +// ACCESSORS +int MyInteger::getValue() const +{ + return d_intValue; +} + +} // close namespace UsageExample + +//============================================================================= +// MAIN PROGRAM +//----------------------------------------------------------------------------- + +int main(int argc, char *argv[]) +{ + int test = argc > 1 ? atoi(argv[1]) : 0; + + verbose = argc > 2; + veryVerbose = argc > 3; + veryVeryVerbose = argc > 4; + + setbuf(stdout, NULL); // Use unbuffered output + + printf("TEST " __FILE__ " CASE %d\n", test); + + bslma::TestAllocator testAllocator(veryVeryVerbose); + Z = &testAllocator; + + switch (test) { case 0: // Zero is always the leading case. + case 3: { + // -------------------------------------------------------------------- + // TESTING USAGE EXAMPLE + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting Usage Example" + "\n=====================\n"); + using namespace UsageExample; +// Then, we create an object, 'myInteger', of type 'MyInteger': +//.. + bsls::ObjectBuffer buffer; + MyInteger *myInteger = &buffer.object(); + new (myInteger) MyInteger(1); +//.. +// Notice that we use an 'ObjectBuffer' to allow us to safely invoke the +// destructor explicitly. +// +// Now, we define a primitive integer: +//.. + int scalarInteger = 2; +//.. +// Finally, we use the uniform 'bslalg::ScalarDestructionPrimitives:destroy' +// method to destroy both 'myInteger' and 'scalarInteger': +//.. + bslalg::ScalarDestructionPrimitives::destroy(myInteger); + bslalg::ScalarDestructionPrimitives::destroy(&scalarInteger); +//.. + } break; + case 2: { + // -------------------------------------------------------------------- + // TESTING destroy + // + // Concerns: + //: 1. The 'destroy' acts as a uniform interface to destroy objects of + //: different types as expected. + // + // Plan: + //: 1. Construct objects of types that have different type traits + //: declared. Call the 'destroy' method on them and verify they + //: are destroyed as expected. + // + // Testing: + // void destroy(T *dst); + // -------------------------------------------------------------------- + + if (verbose) printf("\nTesting 'destroy'\n"); + + if (verbose) printf("\n\t...with TestTypeNoAlloc.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with TestType.\n"); + testDestroy(false); + + if (verbose) printf("\n\t...with BitwiseCopyableTestType.\n"); + testDestroy(false); + + if(verbose) printf("\nNegative testing\n"); + { + bsls::AssertFailureHandlerGuard g( + bsls::AssertTest::failTestDriver); + + int * null = 0; + ASSERT_SAFE_FAIL(Obj::destroy(null)); + + int x = 0; + ASSERT_SAFE_PASS(Obj::destroy(&x)); + } + } break; + case 1: { + // -------------------------------------------------------------------- + // BREATHING TEST + // + // Concerns: + //: 1. That the basic 'destroy' algorithm works as intended. + // + // Plan: + //: 1. Construct objects in a range and use 'destroy' to destroy + //: them. Make sure all memory is deallocated. + // + // Testing: + // BREATHING TEST + // -------------------------------------------------------------------- + + if (verbose) printf("\nBREATHING TEST" + "\n==============\n"); + + bslma::TestAllocator ta(veryVerbose); + + numDestructorCalls = 0; + { + const T VALUE('a'); + + bsls::ObjectBuffer scalar; + T *buffer = &scalar.object(); + + new (buffer) T(VALUE, &ta); + + Obj::destroy(buffer); + + ASSERT(1 == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + numDestructorCalls = 0; + { + const TNA VALUE('a'); + + bsls::ObjectBuffer scalar; + TNA *buffer = &scalar.object(); + + new (buffer) TNA(VALUE, &ta); + + Obj::destroy(buffer); + + ASSERT(1 == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + numDestructorCalls = 0; + { + const BCT VALUE('a'); + + bsls::ObjectBuffer scalar; + BCT *buffer = &scalar.object(); + + new (buffer) BCT(VALUE, &ta); + + Obj::destroy(buffer); + + ASSERT(0 == numDestructorCalls); + } + ASSERT(0 == ta.numMismatches()); + ASSERT(0 == ta.numBytesInUse()); + + } break; + default: { + fprintf(stderr, "WARNING: CASE `%d' NOT FOUND.\n", test); + testStatus = -1; + } + } + + if (testStatus > 0) { + fprintf(stderr, "Error, non-zero test status = %d.\n", testStatus); + } + + return testStatus; +} + +// ---------------------------------------------------------------------------- +// Copyright (C) 2012 Bloomberg L.P. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// ----------------------------- END-OF-FILE ---------------------------------- From bf11d7ac454a74b4eb550f45ec978406d8632a85 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:53:24 -0500 Subject: [PATCH 42/49] remove extra blank line --- groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp index 5cfd7de7f8..5c80146d7a 100644 --- a/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_scalardestructionprimitives.t.cpp @@ -42,7 +42,6 @@ using namespace BloombergLP; // [ 2] void destroy(T *dst); //----------------------------------------------------------------------------- // [ 1] BREATHING TEST - //============================================================================= // STANDARD BDE ASSERT TEST MACRO //----------------------------------------------------------------------------- From 4f3e1d43c37d83c93c89adaaed6b74717ee24eef Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:54:48 -0500 Subject: [PATCH 43/49] remove windows newlines --- groups/bsl/bsls/bsls_ident.t.cpp | 45 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/groups/bsl/bsls/bsls_ident.t.cpp b/groups/bsl/bsls/bsls_ident.t.cpp index be140baabf..6df595347a 100644 --- a/groups/bsl/bsls/bsls_ident.t.cpp +++ b/groups/bsl/bsls/bsls_ident.t.cpp @@ -1,10 +1,9 @@ // bsls_ident.t.cpp -*-C++-*- - - // *** The format of this component test driver is non-standard. *** -#include // #include // included below in usage example. +#include + #include // 'atoi' #include #include @@ -37,26 +36,26 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING From 62cabead1f7e6a918a928806ade3ebe1c5167fbf Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:57:12 -0500 Subject: [PATCH 44/49] remove windows newlines --- groups/bsl/bsls/bsls_alignedbuffer.t.cpp | 42 ++++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp index 95674886d3..a5b1ab2f36 100644 --- a/groups/bsl/bsls/bsls_alignedbuffer.t.cpp +++ b/groups/bsl/bsls/bsls_alignedbuffer.t.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include @@ -47,26 +47,26 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING From 08de649025b74af17d1565489e13350a481fe012 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:57:38 -0500 Subject: [PATCH 45/49] remove windoze newlines --- groups/bsl/bslalg/bslalg_rangecompare.t.cpp | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp index a764ff0086..3c309d6d98 100644 --- a/groups/bsl/bslalg/bslalg_rangecompare.t.cpp +++ b/groups/bsl/bslalg/bslalg_rangecompare.t.cpp @@ -74,26 +74,26 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL HELPER FUNCTIONS FOR TESTING From a8bc28845443f300cbee68b57a9be6bcf741aec7 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:58:52 -0500 Subject: [PATCH 46/49] remove windoze newlines --- groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp | 40 ++++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp index 7c1b57419e..7f34f81d89 100644 --- a/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp +++ b/groups/bsl/bslstl/bslstl_stdexceptutil.t.cpp @@ -60,26 +60,26 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING From 2209ca152bf745fb12bb964cf4c5715475fe94b3 Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Wed, 9 Jan 2013 13:59:27 -0500 Subject: [PATCH 47/49] remove windows newlinese --- groups/bsl/bslstl/bslstl_pair.t.cpp | 40 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_pair.t.cpp b/groups/bsl/bslstl/bslstl_pair.t.cpp index f61a9e684d..c6585f5fc4 100644 --- a/groups/bsl/bslstl/bslstl_pair.t.cpp +++ b/groups/bsl/bslstl/bslstl_pair.t.cpp @@ -91,26 +91,26 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -//============================================================================= -// STANDARD BDE TEST DRIVER MACROS -//----------------------------------------------------------------------------- - -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +//============================================================================= +// STANDARD BDE TEST DRIVER MACROS +//----------------------------------------------------------------------------- + +#define ASSERT BSLS_BSLTESTUTIL_ASSERT +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV + +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING From 3e6ab7bf29c664fae2db7b83db903631b21d90a6 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 9 Jan 2013 15:12:25 -0500 Subject: [PATCH 48/49] only adding one line --- .../bslalg_arraydestructionprimitives.t.cpp | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp index 1a240964e3..4d3ea2def0 100644 --- a/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp +++ b/groups/bsl/bslalg/bslalg_arraydestructionprimitives.t.cpp @@ -44,45 +44,53 @@ using namespace BloombergLP; //----------------------------------------------------------------------------- // [ 1] BREATHING TEST -//========================================================================== +//============================================================================= // STANDARD BDE ASSERT TEST MACRO -//-------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // NOTE: THIS IS A LOW-LEVEL COMPONENT AND MAY NOT USE ANY C++ LIBRARY // FUNCTIONS, INCLUDING IOSTREAMS. -static int testStatus = 0; +int testStatus = 0; namespace { void aSsErT(int c, const char *s, int i) { - if (c) { + if (c) + { printf("Error " __FILE__ "(%d): %s (failed)\n", i, s); if (testStatus >= 0 && testStatus <= 100) ++testStatus; } } - } // close unnamed namespace +# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } //============================================================================= -// STANDARD BDE TEST DRIVER MACROS +// STANDARD BDE LOOP-ASSERT TEST MACROS //----------------------------------------------------------------------------- +// NOTE: This implementation of LOOP_ASSERT macros must use printf since +// cout uses new and be called during exception testing. +#define LOOP_ASSERT(I,X) { \ + if (!(X)) { printf("%s: %d\n", #I, I); aSsErT(1, #X, __LINE__); } } -#define ASSERT BSLS_BSLTESTUTIL_ASSERT -#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT -#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT -#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT -#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT -#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT -#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT -#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT -#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT -#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV - -#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. -#define P BSLS_BSLTESTUTIL_P // Print identifier and value. -#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. -#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). -#define L_ BSLS_BSLTESTUTIL_L_ // current Line number +#define LOOP2_ASSERT(I,J,X) { \ + if (!(X)) { printf("%s: %d\t%s: %d\n", #I, I, #J, J); \ + aSsErT(1, #X, __LINE__); } } +#define LOOP3_ASSERT(I,J,K,X) { \ + if (!(X)) { printf("%s: %d\t%s: %c\t%s: %c\n", #I, I, #J, J, #K, K); \ + aSsErT(1, #X, __LINE__); } } + +#define LOOP4_ASSERT(I,J,K,L,X) { \ + if (!(X)) { printf("%s: %d\t%s: %d\t%s: %d\t%s: %d\n", \ + #I, I, #J, J, #K, K, #L, L); aSsErT(1, #X, __LINE__); } } + +//============================================================================= +// SEMI-STANDARD TEST OUTPUT MACROS +//----------------------------------------------------------------------------- +// #define P(X) cout << #X " = " << (X) << endl; // Print identifier and value. +#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. +//#define P_(X) cout << #X " = " << (X) << ", " << flush; // P(X) without '\n' +#define L_ __LINE__ // current Line number +#define T_ printf("\t"); // Print a tab (w/o newline) //============================================================================= // SEMI-STANDARD NEGATIVE-TESTING MACROS From b70f99884082798bcc9989e44e34965fba5a221c Mon Sep 17 00:00:00 2001 From: Wei-Yeh Lee Date: Tue, 15 Jan 2013 15:41:01 -0500 Subject: [PATCH 49/49] solved 11 reload problems --- groups/bsl/bslstl/bslstl_deque.t.cpp | 134 ++++++++++++++------------- 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/groups/bsl/bslstl/bslstl_deque.t.cpp b/groups/bsl/bslstl/bslstl_deque.t.cpp index b1a7845978..82ea42f866 100644 --- a/groups/bsl/bslstl/bslstl_deque.t.cpp +++ b/groups/bsl/bslstl/bslstl_deque.t.cpp @@ -1,12 +1,12 @@ // bslstl_deque.t.cpp -*-C++-*- - +#include #include #include #include #include #include // for testing only #include // for testing only - +#include #include #include #include // for testing only @@ -173,7 +173,8 @@ void aSsErT(int c, const char *s, int i) } // close unnamed namespace -# define ASSERT(X) { aSsErT(!(X), #X, __LINE__); } +#define ASSERT BSLS_BSLTESTUTIL_ASSERT + //============================================================================= // STANDARD BDE LOOP-ASSERT TEST MACROS @@ -181,44 +182,25 @@ void aSsErT(int c, const char *s, int i) // NOTE: This implementation of LOOP_ASSERT macros must use printf since // cout uses new and must not be called during exception testing. -#define LOOP_ASSERT(I,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - -#define LOOP2_ASSERT(I,J,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\t"); \ - printf("%s", #J ": "); dbg_print(J); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - -#define LOOP3_ASSERT(I,J,K,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\t"); \ - printf("%s", #J ": "); dbg_print(J); printf("\t"); \ - printf("%s", #K ": "); dbg_print(K); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - -#define LOOP4_ASSERT(I,J,K,L,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\t"); \ - printf("%s", #J ": "); dbg_print(J); printf("\t"); \ - printf("%s", #K ": "); dbg_print(K); printf("\t"); \ - printf("%s", #L ": "); dbg_print(L); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - -#define LOOP5_ASSERT(I,J,K,L,M,X) { \ - if (!(X)) { printf("%s", #I ": "); dbg_print(I); printf("\t"); \ - printf("%s", #J ": "); dbg_print(J); printf("\t"); \ - printf("%s", #K ": "); dbg_print(K); printf("\t"); \ - printf("%s", #L ": "); dbg_print(L); printf("\t"); \ - printf("%s", #M ": "); dbg_print(M); printf("\n"); \ - fflush(stdout); aSsErT(1, #X, __LINE__); } } - +#define LOOP_ASSERT BSLS_BSLTESTUTIL_LOOP_ASSERT +#define LOOP0_ASSERT BSLS_BSLTESTUTIL_LOOP0_ASSERT +#define LOOP1_ASSERT BSLS_BSLTESTUTIL_LOOP1_ASSERT +#define LOOP2_ASSERT BSLS_BSLTESTUTIL_LOOP2_ASSERT +#define LOOP3_ASSERT BSLS_BSLTESTUTIL_LOOP3_ASSERT +#define LOOP4_ASSERT BSLS_BSLTESTUTIL_LOOP4_ASSERT +#define LOOP5_ASSERT BSLS_BSLTESTUTIL_LOOP5_ASSERT +#define LOOP6_ASSERT BSLS_BSLTESTUTIL_LOOP6_ASSERT +#define ASSERTV BSLS_BSLTESTUTIL_ASSERTV //============================================================================= // SEMI-STANDARD TEST OUTPUT MACROS //----------------------------------------------------------------------------- -#define Q(X) printf("<| " #X " |>\n"); // Quote identifier literally. -#define P(X) dbg_print(#X " = ", X, "\n") // Print identifier and value. -#define P_(X) dbg_print(#X " = ", X, ", ") // P(X) without '\n' -#define L_ __LINE__ // current Line number -#define T_ putchar('\t'); // Print a tab (w/o newline) +#define Q BSLS_BSLTESTUTIL_Q // Quote identifier literally. +//#define P(X) debugprint(X, #X " = ", "\n") // Print identifier and value. +//#define P_(X) debugprint(X, #X " = ", ", ") // P(X) without '\n' +#define P BSLS_BSLTESTUTIL_P // Print identifier and value. +#define P_ BSLS_BSLTESTUTIL_P_ // P(X) without '\n'. +#define T_ BSLS_BSLTESTUTIL_T_ // Print a tab (w/o newline). +#define L_ BSLS_BSLTESTUTIL_L_ // current Line number //============================================================================= // GLOBAL TYPEDEFS/CONSTANTS FOR TESTING @@ -294,91 +276,118 @@ const int NUM_INTERNAL_STATE_TEST = 10; // Fundamental-type-specific print functions. inline -void dbg_print(char c) +void debugprint(char c) { printf("%c", c); fflush(stdout); } inline -void dbg_print(unsigned char c) +void debugprint(unsigned char c) { printf("%c", c); fflush(stdout); } inline -void dbg_print(signed char c) +void debugprint(signed char c) { printf("%c", c); fflush(stdout); } inline -void dbg_print(short val) +void debugprint(short val) { printf("%d", (int)val); fflush(stdout); } inline -void dbg_print(unsigned short val) +void debugprint(unsigned short val) { printf("%d", (int)val); fflush(stdout); } inline -void dbg_print(int val) +void debugprint(int val) { printf("%d", val); fflush(stdout); } inline -void dbg_print(bsls::Types::Int64 val) +void debugprint(bsls::Types::Int64 val) { printf("%lld", val); fflush(stdout); } #if defined(BSLS_PLATFORM_OS_AIX) inline -void dbg_print(unsigned int val) +void debugprint(unsigned int val) { printf("%d", val); fflush(stdout); } #endif inline -void dbg_print(size_t val) +void debugprint(size_t val) { printf("%llu", (Uint64) val); fflush(stdout); } inline -void dbg_print(float val) +void debugprint(float val) { printf("'%f'", (double)val); fflush(stdout); } inline -void dbg_print(double val) +void debugprint(double val) { printf("'%f'", val); fflush(stdout); } inline -void dbg_print(const char* s) +void debugprint(const char* s) { printf("\"%s\"", s); fflush(stdout); } -// Deque-specific print function. +//// Deque-specific print function. +//template +//void callDebugprint(const bsl::deque& v) +//{ +// +// if (v.empty()) { +// printf(""); +// } +// else { +// for (size_t i = 0; i < v.size(); ++i) { +// debugprint(v[i]); +// } +// } +// fflush(stdout); +//} +// +//// Generic debug print function (3-arguments). +//template +//void callDebugprint(const T& val, const char *s, const char *nl) +//{ +// printf("%s", s); +// debugprint(val); +// printf("%s", nl); +// fflush(stdout); +//} + template -void dbg_print(const bsl::deque& v) +void debugprint(const bsl::deque& v) { + if (v.empty()) { printf(""); } else { for (size_t i = 0; i < v.size(); ++i) { - dbg_print(v[i]); + debugprint(v[i]); } } fflush(stdout); } // Generic debug print function (3-arguments). -template -void dbg_print(const char* s, const T& val, const char* nl) +template class val; +void debugprint(const T& val, const char *s, const char *nl) { - printf("%s", s); dbg_print(val); + printf("%s", s); + debugprint(val); printf("%s", nl); fflush(stdout); } @@ -751,7 +760,7 @@ bool operator<(const TestType& lhs, const TestType& rhs) } // TestType-specific print function. -void dbg_print(const TestType& rhs) +void debugprint(const TestType& rhs) { printf("%c", rhs.value()); fflush(stdout); @@ -833,7 +842,7 @@ bool operator==(const SmallTestTypeNoAlloc& lhs, } // SmallTestType-specific print function. -void dbg_print(const SmallTestTypeNoAlloc& rhs) +void debugprint(const SmallTestTypeNoAlloc& rhs) { printf("%c", rhs.value()); fflush(stdout); @@ -916,7 +925,7 @@ bool operator==(const MediumTestTypeNoAlloc& lhs, } // MediumTestType-specific print function. -void dbg_print(const MediumTestTypeNoAlloc& rhs) +void debugprint(const MediumTestTypeNoAlloc& rhs) { printf("%c", rhs.value()); fflush(stdout); @@ -999,7 +1008,7 @@ bool operator==(const LargeTestTypeNoAlloc& lhs, } // LargeTestType-specific print function. -void dbg_print(const LargeTestTypeNoAlloc& rhs) +void debugprint(const LargeTestTypeNoAlloc& rhs) { printf("%c", rhs.value()); fflush(stdout); @@ -6219,8 +6228,8 @@ void TestDriver::testCase8() gg(&mX, SPEC); const Obj& X = mX; if (veryVerbose) { - printf("\t g = "); dbg_print(g(SPEC)); printf("\n"); - printf("\tgg = "); dbg_print(X); printf("\n"); + printf("\t g = "); debugprint(g(SPEC)); printf("\n"); + printf("\tgg = "); debugprint(X); printf("\n"); } const int TOTAL_BLOCKS_BEFORE = (int) testAllocator.numBlocksTotal(); const int IN_USE_BYTES_BEFORE = (int) testAllocator.numBytesInUse(); @@ -7879,7 +7888,6 @@ void TestDriver::testCase1() int main(int argc, char *argv[]) { int test = argc > 1 ? atoi(argv[1]) : 0; - verbose = argc > 2; veryVerbose = argc > 3; veryVeryVerbose = argc > 4;