├── .clang-format ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ch01 ├── README.md ├── ex1_09.cpp ├── ex1_10.cpp ├── ex1_11.cpp ├── ex1_20.cpp ├── ex1_21.cpp ├── ex1_22.cpp └── ex1_23.cpp ├── ch02 ├── README.md ├── ex2_04.cpp ├── ex2_34.cpp ├── ex2_35.cpp ├── ex2_42.h ├── ex2_42_1.cpp ├── ex2_42_2.cpp └── ex2_42_3.cpp ├── ch03 ├── README.md ├── ex3_01a.cpp ├── ex3_01b.cpp ├── ex3_02a.cpp ├── ex3_02b.cpp ├── ex3_04a.cpp ├── ex3_04b.cpp ├── ex3_05a.cpp ├── ex3_05b.cpp ├── ex3_06.cpp ├── ex3_08.cpp ├── ex3_10.cpp ├── ex3_14.cpp ├── ex3_15.cpp ├── ex3_16.cpp ├── ex3_17.cpp ├── ex3_18.cpp ├── ex3_19.cpp ├── ex3_20.cpp ├── ex3_21.cpp ├── ex3_22.cpp ├── ex3_23.cpp ├── ex3_24.cpp ├── ex3_25.cpp ├── ex3_31.cpp ├── ex3_32.cpp ├── ex3_35.cpp ├── ex3_36.cpp ├── ex3_39.cpp ├── ex3_40.cpp ├── ex3_41.cpp ├── ex3_42.cpp ├── ex3_43.cpp ├── ex3_44.cpp └── ex3_45.cpp ├── ch04 ├── README.md ├── ex4_21.cpp ├── ex4_22.cpp └── ex4_28.cpp ├── ch05 ├── README.md ├── ex5_05.cpp ├── ex5_06.cpp ├── ex5_09.cpp ├── ex5_10.cpp ├── ex5_11.cpp ├── ex5_12.cpp ├── ex5_14.cpp ├── ex5_17.cpp ├── ex5_19.cpp ├── ex5_20.cpp ├── ex5_21.cpp ├── ex5_23.cpp ├── ex5_24.cpp └── ex5_25.cpp ├── ch06 ├── Chapter6.h ├── README.md ├── ex6_04.cpp ├── ex6_10.cpp ├── ex6_11.cpp ├── ex6_12.cpp ├── ex6_17.cpp ├── ex6_21.cpp ├── ex6_22.cpp ├── ex6_23.cpp ├── ex6_25_26.cpp ├── ex6_27.cpp ├── ex6_33.cpp ├── ex6_42.cpp ├── ex6_44.cpp ├── ex6_47.cpp ├── ex6_51.cpp ├── ex6_54_55_56.cpp ├── fact.cc └── factMain.cc ├── ch07 ├── README.md ├── ex7_01.cpp ├── ex7_02.h ├── ex7_03.cpp ├── ex7_04.h ├── ex7_05.h ├── ex7_06.h ├── ex7_07.cpp ├── ex7_09.h ├── ex7_11.cpp ├── ex7_11.h ├── ex7_12.h ├── ex7_13.cpp ├── ex7_15.h ├── ex7_21.h ├── ex7_22.h ├── ex7_23.h ├── ex7_24.h ├── ex7_26.cpp ├── ex7_26.h ├── ex7_27.h ├── ex7_27_TEST.cpp ├── ex7_31.h ├── ex7_32.h ├── ex7_41.cpp ├── ex7_41.h ├── ex7_41_TEST.cpp ├── ex7_43.cpp ├── ex7_50.h ├── ex7_53.h └── ex7_57.h ├── ch08 ├── README.md ├── ex8_02.cpp ├── ex8_04.cpp ├── ex8_05.cpp ├── ex8_06.cpp ├── ex8_07.cpp ├── ex8_08.cpp ├── ex8_09.cpp ├── ex8_10.cpp ├── ex8_11.cpp └── ex8_13.cpp ├── ch09 ├── README.md ├── ex9_13.cpp ├── ex9_14.cpp ├── ex9_15.cpp ├── ex9_16.cpp ├── ex9_18.cpp ├── ex9_19.cpp ├── ex9_20.cpp ├── ex9_22.cpp ├── ex9_24.cpp ├── ex9_26.cpp ├── ex9_27.cpp ├── ex9_31_1.cpp ├── ex9_31_2.cpp ├── ex9_32.cpp ├── ex9_33.cpp ├── ex9_34.cpp ├── ex9_38.cpp ├── ex9_41.cpp ├── ex9_43.cpp ├── ex9_44.cpp ├── ex9_45.cpp ├── ex9_46.cpp ├── ex9_47_1.cpp ├── ex9_47_2.cpp ├── ex9_49.cpp ├── ex9_50.cpp ├── ex9_51.cpp └── ex9_52.cpp ├── ch10 ├── README.md ├── ex10_01_02.cpp ├── ex10_03_04.cpp ├── ex10_05.cpp ├── ex10_06.cpp ├── ex10_07.cpp ├── ex10_09.cpp ├── ex10_11.cpp ├── ex10_12.cpp ├── ex10_13.cpp ├── ex10_16.cpp ├── ex10_17.cpp ├── ex10_18_19.cpp ├── ex10_20.cpp ├── ex10_21.cpp ├── ex10_22.cpp ├── ex10_24.cpp ├── ex10_25.cpp ├── ex10_27.cpp ├── ex10_28.cpp ├── ex10_29.cpp ├── ex10_30.cpp ├── ex10_31.cpp ├── ex10_32.cpp ├── ex10_33.cpp ├── ex10_34_35_36_37.cpp └── ex10_42.cpp ├── ch11 ├── README.md ├── ex11_11.cpp ├── ex11_12_13.cpp ├── ex11_14.cpp ├── ex11_18.cpp ├── ex11_20.cpp ├── ex11_23.cpp ├── ex11_24_25_26.cpp ├── ex11_27_28_29_30.cpp ├── ex11_31.cpp ├── ex11_32.cpp ├── ex11_33.cpp ├── ex11_38.cpp ├── ex11_3_4.cpp ├── ex11_7.cpp ├── ex11_8.cpp └── ex11_9_10.cpp ├── ch12 ├── README.md ├── ex12_02.h ├── ex12_02_TEST.cpp ├── ex12_06.cpp ├── ex12_07.cpp ├── ex12_10.cpp ├── ex12_11.cpp ├── ex12_12.cpp ├── ex12_13.cpp ├── ex12_14.cpp ├── ex12_15.cpp ├── ex12_16.cpp ├── ex12_17_18.cpp ├── ex12_19.cpp ├── ex12_19.h ├── ex12_20.cpp ├── ex12_22.cpp ├── ex12_22.h ├── ex12_23.cpp ├── ex12_24.cpp ├── ex12_26.cpp ├── ex12_27_30.cpp ├── ex12_27_30.h ├── ex12_27_30_TEST.cpp ├── ex12_28.cpp ├── ex12_32.cpp ├── ex12_32.h ├── ex12_33.cpp └── ex12_33.h ├── ch13 ├── README.md ├── ex13_05.h ├── ex13_08.h ├── ex13_11.h ├── ex13_13.cpp ├── ex13_17_1.cpp ├── ex13_17_2.cpp ├── ex13_17_3.cpp ├── ex13_18.cpp ├── ex13_18.h ├── ex13_19.h ├── ex13_22.h ├── ex13_26.cpp ├── ex13_26.h ├── ex13_27.h ├── ex13_28.cpp ├── ex13_28.h ├── ex13_30.h ├── ex13_31.h ├── ex13_34_36_37.cpp ├── ex13_34_36_37.h ├── ex13_34_36_37_TEST.cpp ├── ex13_39.cpp ├── ex13_39.h ├── ex13_40.cpp ├── ex13_40.h ├── ex13_42.cpp ├── ex13_42_StrVec.cpp ├── ex13_42_StrVec.h ├── ex13_42_TextQuery.cpp ├── ex13_42_TextQuery.h ├── ex13_44_47.cpp ├── ex13_44_47.h ├── ex13_48.cpp ├── ex13_49_Message.cpp ├── ex13_49_Message.h ├── ex13_49_Message_TEST.cpp ├── ex13_49_StrVec.cpp ├── ex13_49_StrVec.h ├── ex13_49_String.cpp ├── ex13_49_String.h ├── ex13_53.cpp ├── ex13_53.h ├── ex13_53_test.cpp └── ex13_58.cpp ├── ch14 ├── README.md ├── ex14_02.cpp ├── ex14_02.h ├── ex14_02_TEST.cpp ├── ex14_05.cpp ├── ex14_05.h ├── ex14_05_TEST.cpp ├── ex14_07.cpp ├── ex14_07.h ├── ex14_07_TEST.cpp ├── ex14_15.cpp ├── ex14_15.h ├── ex14_15_TEST.cpp ├── ex14_16_StrBlob.cpp ├── ex14_16_StrBlob.h ├── ex14_16_StrBlobTest.cpp ├── ex14_16_StrVec.cpp ├── ex14_16_StrVec.h ├── ex14_16_StrVecMain.cpp ├── ex14_16_String.cpp ├── ex14_16_String.h ├── ex14_16_StringMain.cpp ├── ex14_18_StrBlob.cpp ├── ex14_18_StrBlob.h ├── ex14_18_StrBlobTest.cpp ├── ex14_18_StrVec.cpp ├── ex14_18_StrVec.h ├── ex14_18_StrVecMain.cpp ├── ex14_18_String.cpp ├── ex14_18_String.h ├── ex14_18_StringMain.cpp ├── ex14_22.cpp ├── ex14_22.h ├── ex14_22_TEST.cpp ├── ex14_23.cpp ├── ex14_23.h ├── ex14_23_TEST.cpp ├── ex14_24.cpp ├── ex14_24.h ├── ex14_24_TEST.cpp ├── ex14_26_StrBlob.cpp ├── ex14_26_StrBlob.h ├── ex14_26_StrBlobTest.cpp ├── ex14_26_StrVec.cpp ├── ex14_26_StrVec.h ├── ex14_26_StrVecMain.cpp ├── ex14_26_String.cpp ├── ex14_26_String.h ├── ex14_26_StringMain.cpp ├── ex14_27_28_StrBlob.cpp ├── ex14_27_28_StrBlob.h ├── ex14_27_28_StrBlobTest.cpp ├── ex14_30_StrBlob.cpp ├── ex14_30_StrBlob.h ├── ex14_30_StrBlobTest.cpp ├── ex14_32.cpp ├── ex14_32.h ├── ex14_35.cpp ├── ex14_36.cpp ├── ex14_37.cpp ├── ex14_38_39.cpp ├── ex14_40.cpp ├── ex14_42.cpp ├── ex14_43.cpp ├── ex14_44.cpp ├── ex14_45.cpp ├── ex14_45.h ├── ex14_45_TEST.cpp ├── ex14_49.cpp ├── ex14_49.h └── ex14_49_TEST.cpp ├── ch15 ├── ex15.1.2.3 │ ├── CppPrimer.pro │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.11 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.12.13.14 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.15.16.17 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── disc_quote.cpp │ ├── disc_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.18.19.20 │ └── main.cpp ├── ex15.21.22 │ └── main.cpp ├── ex15.23.cpp ├── ex15.24.25.cpp ├── ex15.26 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── disc_quote.cpp │ ├── disc_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.27 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── disc_quote.cpp │ ├── disc_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.28.29 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── disc_quote.cpp │ ├── disc_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.30 │ ├── basket.cpp │ ├── basket.h │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── disc_quote.cpp │ ├── disc_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.31.32.33.cpp ├── ex15.34.35.36.38 │ ├── StrBlob.h │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15.39.40 │ ├── StrBlob.h │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15.42_b │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryhistory.cpp │ ├── queryhistory.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── test.txt │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15.42_c │ ├── andquery.cpp │ ├── andquery.h │ ├── binaryquery.cpp │ ├── binaryquery.h │ ├── main.cpp │ ├── notquery.cpp │ ├── notquery.h │ ├── orquery.cpp │ ├── orquery.h │ ├── query.cpp │ ├── query.h │ ├── query_base.cpp │ ├── query_base.h │ ├── queryresult.cpp │ ├── queryresult.h │ ├── test.txt │ ├── textquery.cpp │ ├── textquery.h │ ├── wordquery.cpp │ └── wordquery.h ├── ex15.5.6 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h ├── ex15.7 │ ├── bulk_quote.cpp │ ├── bulk_quote.h │ ├── limit_quote.cpp │ ├── limit_quote.h │ ├── main.cpp │ ├── quote.cpp │ └── quote.h └── ex15.8.9.10 │ └── ex15.8.9.10.cpp ├── ch16 ├── ex16.1.2.3 │ └── main.cpp ├── ex16.12.13 │ ├── Blob.h │ ├── blobptr.h │ └── main.cpp ├── ex16.14.15 │ ├── Screen.h │ └── main.cpp ├── ex16.16 │ ├── main.cpp │ └── vec.h ├── ex16.17.18 │ └── main.cpp ├── ex16.19.20 │ └── main.cpp ├── ex16.21.22 │ ├── DebugDelete.h │ ├── StrBlob.h │ ├── main.cpp │ ├── wy_queryresult.cpp │ ├── wy_queryresult.h │ ├── wy_textquery.cpp │ └── wy_textquery.h ├── ex16.24 │ ├── Blob.h │ ├── blobptr.h │ └── main.cpp ├── ex16.25.26 │ └── main.cpp ├── ex16.28 │ ├── DebugDelete.h │ ├── main.cpp │ ├── shared_pointer.h │ └── unique_pointer.h ├── ex16.29 │ ├── Blob.h │ ├── DebugDelete.h │ ├── main.cpp │ ├── shared_pointer.h │ └── unique_pointer.h ├── ex16.32.33.34.35.36 │ └── main.cpp ├── ex16.37.38.39 │ └── main.cpp ├── ex16.4 │ └── main.cpp ├── ex16.40 │ └── main.cpp ├── ex16.41 │ └── main.cpp ├── ex16.42.43.44.45.46 │ └── main.cpp ├── ex16.47 │ └── main.cpp ├── ex16.48 │ └── main.cpp ├── ex16.49.50 │ └── main.cpp ├── ex16.5 │ └── main.cpp ├── ex16.51.52 │ └── main.cpp ├── ex16.53.54.55 │ └── main.cpp ├── ex16.56.57 │ └── main.cpp ├── ex16.58.59 │ ├── strvec.cpp │ ├── strvec.h │ └── vec.h ├── ex16.6 │ └── main.cpp ├── ex16.60.61 │ └── main.cpp ├── ex16.62 │ ├── Sales_data.cc │ ├── Sales_data.h │ └── main.cpp ├── ex16.63.64 │ └── main.cpp ├── ex16.65.66.67 │ └── main.cpp ├── ex16.7.8 │ └── main.cpp └── ex16.9.10.11 │ └── main.cpp ├── ch17 ├── ex17.1.2 │ └── main.cpp ├── ex17.10 │ └── main.cpp ├── ex17.11.12.13 │ └── main.cpp ├── ex17.14.15.16 │ └── main.cpp ├── ex17.17.18 │ └── main.cpp ├── ex17.19.20 │ └── main.cpp ├── ex17.21 │ ├── data │ │ └── record.txt │ └── main.cpp ├── ex17.22 │ └── ex17.22 │ │ └── main.cpp ├── ex17.28.29.30 │ └── main.cpp ├── ex17.3 │ ├── main.cpp │ ├── textquery.cpp │ └── textquery.h ├── ex17.4.5.6.7.8 │ ├── Sales_data.cpp │ ├── Sales_data.h │ └── main.cpp ├── ex17.9 │ └── main.cpp └── ex_33.cpp ├── ch18 ├── README.md ├── ex18.1.2.3 │ └── main.cpp ├── ex18.12.13.14 │ └── main.cpp └── ex18.15.16.17 │ └── main.cpp ├── data ├── book.txt ├── even.txt ├── given_to_transform.txt ├── input.txt ├── letter.txt ├── odd.txt ├── phonenumbers.txt ├── storyDataFile.txt ├── word_transformation.txt └── word_transformation_bad.txt ├── generate_format_command.py └── include └── Sales_item.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS 2 | .DS_Store 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | 22 | # Compiled Static libraries 23 | *.lai 24 | *.la 25 | *.a 26 | *.lib 27 | 28 | # Executables 29 | *.exe 30 | *.out 31 | *.app 32 | -------------------------------------------------------------------------------- /ch01/ex1_09.cpp: -------------------------------------------------------------------------------- 1 | // sum the numbers from 50 to 100 (use while) 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | int sum = 0, val = 50; 8 | while (val <= 100) { 9 | sum += val; 10 | ++val; 11 | } 12 | 13 | std::cout << "the sum is: " << sum << std::endl; 14 | 15 | return 0; 16 | } 17 | 18 | // output: the sum is: 3825 19 | -------------------------------------------------------------------------------- /ch01/ex1_10.cpp: -------------------------------------------------------------------------------- 1 | // prints the numbers from ten down to zero.(use while) 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | int val = 10; 8 | while (val >= 0) { 9 | std::cout << val << std::endl; 10 | --val; 11 | } 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch01/ex1_11.cpp: -------------------------------------------------------------------------------- 1 | // Print each number in the range specified by two integers. 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | int small = 0, big = 0; 8 | std::cout << "please input two integers:"; 9 | std::cin >> small >> big; 10 | 11 | if (small > big) { 12 | int tmp = small; 13 | small = big; 14 | big = tmp; 15 | } 16 | 17 | while (small <= big) { 18 | std::cout << small << " "; 19 | ++small; 20 | } 21 | std::cout << std::endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch01/ex1_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item item; 7 | while (std::cin >> item) std::cout << item << std::endl; 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch01/ex1_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item item1, item2; 7 | std::cin >> item1 >> item2; 8 | if (item1.isbn() == item2.isbn()) { 9 | std::cout << item1 + item2 << std::endl; 10 | return 0; 11 | } 12 | else { 13 | std::cerr << "Data must refer to same ISBN." << std::endl; 14 | return -1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch01/ex1_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item total; 7 | if (std::cin >> total) { 8 | Sales_item trans; 9 | while (std::cin >> trans) { 10 | if (total.isbn() == trans.isbn()) 11 | total += trans; 12 | else { 13 | std::cout << total << std::endl; 14 | total = trans; 15 | } 16 | } 17 | std::cout << total << std::endl; 18 | } 19 | else { 20 | std::cerr << "No data?!" << std::endl; 21 | return -1; 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch01/ex1_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../include/Sales_item.h" 3 | 4 | int main() 5 | { 6 | Sales_item currItem, valItem; 7 | if (std::cin >> currItem) { 8 | int cnt = 1; 9 | while (std::cin >> valItem) { 10 | if (valItem.isbn() == currItem.isbn()) 11 | ++cnt; 12 | else { 13 | std::cout << currItem << " occurs " << cnt << " times " 14 | << std::endl; 15 | currItem = valItem; 16 | cnt = 1; 17 | } 18 | } 19 | 20 | std::cout << currItem << " occurs " << cnt << " times " << std::endl; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch02/ex2_04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | unsigned u = 10, u2 = 42; 6 | std::cout << u2 - u << std::endl; // 32 7 | std::cout << u - u2 << std::endl; // 4294967264 8 | int i = 10, i2 = 42; 9 | std::cout << i2 - i << std::endl; // 32 10 | std::cout << i - i2 << std::endl; // -32 11 | std::cout << i - u << std::endl; // 0 12 | std::cout << u - i << std::endl; // 0 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /ch02/ex2_34.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | int i = 0, &r = i; 6 | auto a = r; // a is an int (r is an alias for i, which has type int) 7 | 8 | const int ci = i, &cr = ci; 9 | auto b = ci; // b is an int (top-level const in ci is dropped) 10 | auto c = cr; // c is an int (cr is an alias for ci whose const is top-level) 11 | auto d = &i; // d is an int* (& ofan int objectis int*) 12 | auto e = &ci; // e is const int*(& of a const object is low-level const) 13 | 14 | const auto f = ci; // deduced type of ci is int; f has type const int 15 | auto& g = ci; // g is a const int& that is bound to ci 16 | 17 | a = 42; 18 | b = 42; 19 | c = 42; 20 | *d = 42; 21 | e = &c; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch02/ex2_42_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ex2_42.h" 3 | 4 | int main() 5 | { 6 | Sales_data book; 7 | double price; 8 | std::cin >> book.bookNo >> book.units_sold >> price; 9 | book.CalcRevenue(price); 10 | book.Print(); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /ch02/ex2_42_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ex2_42.h" 3 | 4 | int main() 5 | { 6 | Sales_data book1, book2; 7 | double price1, price2; 8 | std::cin >> book1.bookNo >> book1.units_sold >> price1; 9 | std::cin >> book2.bookNo >> book2.units_sold >> price2; 10 | book1.CalcRevenue(price1); 11 | book2.CalcRevenue(price2); 12 | 13 | if (book1.bookNo == book2.bookNo) { 14 | book1.AddData(book2); 15 | book1.Print(); 16 | 17 | return 0; 18 | } 19 | else { 20 | std::cerr << "Data must refer to same ISBN" << std::endl; 21 | return -1; // indicate failure 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ch02/ex2_42_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ex2_42.h" 3 | 4 | int main() 5 | { 6 | Sales_data total; 7 | double totalPrice; 8 | if (std::cin >> total.bookNo >> total.units_sold >> totalPrice) { 9 | total.CalcRevenue(totalPrice); 10 | 11 | Sales_data trans; 12 | double transPrice; 13 | while (std::cin >> trans.bookNo >> trans.units_sold >> transPrice) { 14 | trans.CalcRevenue(transPrice); 15 | 16 | if (total.bookNo == trans.bookNo) { 17 | total.AddData(trans); 18 | } 19 | else { 20 | total.Print(); 21 | total.SetData(trans); 22 | } 23 | } 24 | 25 | total.Print(); 26 | 27 | return 0; 28 | } 29 | else { 30 | std::cerr << "No data?!" << std::endl; 31 | return -1; // indicate failure 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ch03/ex3_01a.cpp: -------------------------------------------------------------------------------- 1 | // use `using` for 1.4.1 2 | 3 | #include 4 | 5 | using std::cin; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | int sum = 0, val = 1; 12 | // keep executing the while as long as val is less than or equal to 10 13 | while (val <= 10) { 14 | sum += val; 15 | ++val; 16 | } 17 | cout << "Sum of 1 to 10 inclusive is " << sum << endl; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch03/ex3_02a.cpp: -------------------------------------------------------------------------------- 1 | // read the standard input a line at a time. 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | using std::getline; 10 | 11 | int main() 12 | { 13 | string input; 14 | while (getline(cin, input)) cout << input << endl; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /ch03/ex3_02b.cpp: -------------------------------------------------------------------------------- 1 | // read the standard input a word at a time 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string word; 13 | while (cin >> word) cout << word << endl; 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch03/ex3_04a.cpp: -------------------------------------------------------------------------------- 1 | // read two strings and report whether the strings are equal 2 | // If not, report which of the two is larger. 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cin; 8 | using std::cout; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | string str1, str2; 14 | while (cin >> str1 >> str2) { 15 | if (str1 == str2) 16 | cout << "The two strings are equal." << endl; 17 | else 18 | cout << "The larger string is " << ((str1 > str2) ? str1 : str2); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch03/ex3_04b.cpp: -------------------------------------------------------------------------------- 1 | // read two strings and report whether the strings have the same length 2 | // If not, report which is longer 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cin; 8 | using std::cout; 9 | using std::endl; 10 | 11 | int main() 12 | { 13 | string str1, str2; 14 | while (cin >> str1 >> str2) { 15 | if (str1.size() == str2.size()) 16 | cout << "The two strings have the same length." << endl; 17 | else 18 | cout << "The longer string is " 19 | << ((str1.size() > str2.size()) ? str1 : str2); 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch03/ex3_05a.cpp: -------------------------------------------------------------------------------- 1 | // read strings from the standard input, concatenating what is read into one 2 | // large string. 3 | // Print the concatenated string. 4 | #include 5 | #include 6 | 7 | using std::string; 8 | using std::cin; 9 | using std::cout; 10 | using std::endl; 11 | 12 | int main() 13 | { 14 | string largeStr; 15 | string str; 16 | while (cin >> str) { 17 | largeStr += str; 18 | } 19 | 20 | cout << "The concatenated string is " << largeStr << endl; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch03/ex3_05b.cpp: -------------------------------------------------------------------------------- 1 | // separate adjacent input strings by a space. 2 | #include 3 | #include 4 | 5 | using std::string; 6 | using std::cin; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string largeStr; 13 | string str; 14 | while (cin >> str) { 15 | if (largeStr.empty()) 16 | largeStr += str; 17 | else 18 | largeStr += " " + str; 19 | } 20 | 21 | cout << "The concatenated string is " << largeStr << endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch03/ex3_06.cpp: -------------------------------------------------------------------------------- 1 | // Use a range for to change all the characters in a string to X. 2 | 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string str("a simple string"); 13 | for (auto& c : str) c = 'X'; 14 | cout << str << endl; 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /ch03/ex3_08.cpp: -------------------------------------------------------------------------------- 1 | // Use a range for to change all the characters in a string to X. 2 | 3 | #include 4 | #include 5 | 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | string str("a simple string"); 13 | // use while 14 | decltype(str.size()) i = 0; 15 | while (i < str.size()) { 16 | str[i] = 'X'; 17 | ++i; 18 | } 19 | cout << str << endl; 20 | 21 | // use traditional for 22 | for (i = 0; i < str.size(); ++i) str[i] = 'Y'; 23 | cout << str << endl; 24 | 25 | // I like the first one. 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch03/ex3_10.cpp: -------------------------------------------------------------------------------- 1 | // reads a string of characters including punctuation and writes what was read 2 | // but with the punctuation removed. 3 | 4 | #include 5 | #include 6 | 7 | using std::string; 8 | using std::cout; 9 | using std::cin; 10 | using std::endl; 11 | 12 | int main() 13 | { 14 | string s; 15 | cout << "Enter a string of characters including punctuation." << endl; 16 | while (getline(cin, s)) { 17 | for (auto i : s) 18 | if (!ispunct(i)) cout << i; 19 | cout << endl; 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch03/ex3_14.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | ///@Author PEZY 3 | ///@Date Aug. 2014 4 | ///@Brief 5 | /// read a sequence of ints from cin and 6 | /// store those values in a vector. 7 | /// 8 | 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | std::vector vec; 15 | int i; 16 | while (std::cin >> i) vec.push_back(i); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch03/ex3_15.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | ///@Author PEZY 3 | ///@Date Aug. 2014 4 | ///@Brief 5 | /// read a sequence of strings from cin and 6 | /// store those values in a vector. 7 | /// 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | int main() 14 | { 15 | std::vector vec; 16 | std::string str; 17 | while (std::cin >> str) vec.push_back(str); 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch03/ex3_18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::vector; 4 | 5 | int main() 6 | { 7 | vector ivec{0}; 8 | ivec[0] = 42; 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch03/ex3_19.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | ///@Author PEZY 3 | ///@Date Aug. 2014 4 | ///@Brief 5 | /// List three ways to define a vector and give it ten elements, 6 | /// each with the value 42. 7 | /// Indicate whether there is a preferred way to do so and why. 8 | 9 | #include 10 | #include 11 | using std::vector; 12 | 13 | int main() 14 | { 15 | vector ivec1(10, 42); 16 | vector ivec2{42, 42, 42, 42, 42, 42, 42, 42, 42, 42}; 17 | vector ivec3; 18 | for (int i = 0; i != 10; ++i) ivec3.push_back(42); 19 | std::cout << "The first approach is better!" << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /ch03/ex3_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | using std::cout; 6 | using std::endl; 7 | using std::cin; 8 | 9 | int main() 10 | { 11 | vector ivec; 12 | int i; 13 | while (cin >> i) ivec.push_back(i); 14 | 15 | if (ivec.empty()) { 16 | cout << "input at least one integer." << endl; 17 | return -1; 18 | } 19 | else if (ivec.size() == 1) { 20 | cout << ivec[0] << " don't have any adjacent elements."; 21 | } 22 | else { 23 | for (decltype(ivec.size()) i = 0; i != ivec.size() - 1; ++i) 24 | cout << ivec[i] + ivec[i + 1] << " "; 25 | } 26 | 27 | cout << endl; 28 | 29 | decltype(ivec.size()) size = ivec.size(); 30 | if (size % 2 != 0) 31 | size = size / 2 + 1; 32 | else 33 | size /= 2; 34 | 35 | for (decltype(ivec.size()) i = 0; i != size; ++i) 36 | cout << ivec[i] + ivec[ivec.size() - i - 1] << " "; 37 | cout << endl; 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ch03/ex3_22.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Revise the loop that printed the first paragraph in text 3 | /// to instead change the elements in text that correspond 4 | /// to the first paragraph to all uppercase. 5 | /// After you’ve updated text, print its contents. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using std::vector; 14 | using std::string; 15 | using std::cout; 16 | using std::cin; 17 | using std::endl; 18 | 19 | int main() 20 | { 21 | vector text; 22 | for (string line; getline(cin, line);) text.push_back(line); 23 | 24 | for (auto it = text.begin(); it != text.end() && !it->empty(); ++it) { 25 | for (auto& c : *it) c = toupper(c); 26 | cout << *it << endl; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch03/ex3_23.cpp: -------------------------------------------------------------------------------- 1 | /// 2 | /// Write a program to create a vector with ten int elements. 3 | /// Using an iterator, assign each element a value that is twice its current 4 | /// value. 5 | /// Test your program by printing the vector. 6 | /// 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using std::vector; 13 | using std::iterator; 14 | using std::cout; 15 | using std::endl; 16 | 17 | int main() 18 | { 19 | vector ivec(10, 1); 20 | for (auto it = ivec.begin(); it != ivec.end(); ++it) *it *= 2; 21 | for (auto value : ivec) cout << value << " "; 22 | cout << endl; 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ch03/ex3_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::cout; 7 | using std::endl; 8 | using std::cin; 9 | 10 | int main() 11 | { 12 | int i; 13 | vector ivec; 14 | while (cin >> i) ivec.push_back(i); 15 | 16 | if (ivec.empty()) { 17 | cout << "input at least one integer." << endl; 18 | return -1; 19 | } 20 | else if (ivec.size() == 1) { 21 | cout << *ivec.begin() << " has no adjacent elements."; 22 | } 23 | 24 | for (auto it = ivec.begin(); it + 1 != ivec.end(); ++it) 25 | cout << *it + *(it + 1) << " "; 26 | cout << endl; 27 | 28 | for (auto beg = ivec.begin(), end = ivec.end() - 1; beg <= end; 29 | ++beg, --end) 30 | cout << *beg + *end << " "; 31 | cout << endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch03/ex3_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::cout; 7 | using std::cin; 8 | using std::endl; 9 | 10 | int main() 11 | { 12 | vector scores(11, 0); 13 | unsigned grade; 14 | while (cin >> grade) 15 | if (grade <= 100) ++(*(scores.begin() + grade / 10)); 16 | 17 | for (auto score : scores) cout << score << " "; 18 | cout << endl; 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch03/ex3_31.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::endl; 6 | 7 | int main() 8 | { 9 | int ia[10]; 10 | for (size_t i = 0; i < 10; ++i) ia[i] = i; 11 | 12 | for (auto i : ia) cout << i << " "; 13 | cout << endl; 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /ch03/ex3_32.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::cout; 7 | using std::endl; 8 | using std::vector; 9 | using std::iterator; 10 | 11 | int main() 12 | { 13 | // use array 14 | int ia[10]; 15 | for (size_t i = 0; i < 10; ++i) ia[i] = i; 16 | 17 | int ia2[10]; 18 | for (size_t i = 0; i < 10; ++i) ia2[i] = ia[i]; 19 | 20 | // use vector 21 | vector iv(10); 22 | for (auto iter = iv.begin(); iter != iv.end(); ++iter) 23 | *iter = iter - iv.begin(); 24 | 25 | vector iv2(iv); 26 | 27 | for (auto i : iv2) cout << i << " "; 28 | cout << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch03/ex3_35.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::begin; 5 | using std::end; 6 | using std::cout; 7 | using std::endl; 8 | 9 | int main() 10 | { 11 | int arr[10]; 12 | int* b = begin(arr); 13 | int* e = end(arr); 14 | 15 | for (int* i = b; i != e; ++i) *i = 0; 16 | 17 | for (auto i : arr) cout << i << " "; 18 | cout << endl; 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch03/ex3_39.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | using std::string; 8 | 9 | int main() 10 | { 11 | // use string. 12 | string s1("Mooophy"); 13 | string s2("Pezy"); 14 | 15 | if (s1 == s2) 16 | cout << "same string." << endl; 17 | else if (s1 > s2) 18 | cout << "Mooophy > Pezy" << endl; 19 | else 20 | cout << "Mooophy < Pezy" << endl; 21 | 22 | cout << "=========" << endl; 23 | // use C-Style character strings. 24 | const char* cs1 = "Wangyue"; 25 | const char* cs2 = "Pezy"; 26 | 27 | auto result = strcmp(cs1, cs2); 28 | if (result == 0) 29 | cout << "same string." << endl; 30 | else if (result < 0) 31 | cout << "Wangyue < Pezy" << endl; 32 | else 33 | cout << "Wangyue > Pezy" << endl; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch03/ex3_40.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::endl; 6 | 7 | int main() 8 | { 9 | constexpr size_t new_size = strlen(cstr1) + strlen(" ") + strlen(cstr2) + 1; 10 | char cstr3[new_size]; 11 | 12 | strcpy(cstr3, cstr1); 13 | strcat(cstr3, " "); 14 | strcat(cstr3, cstr2); 15 | 16 | std::cout << cstr3 << std::endl; 17 | } 18 | -------------------------------------------------------------------------------- /ch03/ex3_41.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | using std::cout; 6 | using std::endl; 7 | using std::begin; 8 | using std::end; 9 | 10 | int main() 11 | { 12 | int int_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 13 | vector ivec(begin(int_arr), end(int_arr)); 14 | 15 | for (auto i : ivec) cout << i << " "; 16 | cout << endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch03/ex3_42.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | using std::cout; 6 | using std::endl; 7 | using std::begin; 8 | using std::end; 9 | 10 | int main() 11 | { 12 | vector ivec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 13 | int int_arr[10]; 14 | 15 | for (int* i = begin(int_arr); i != end(int_arr); ++i) 16 | *i = ivec[i - begin(int_arr)]; 17 | 18 | for (auto i : int_arr) cout << i << " "; 19 | cout << endl; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch03/ex3_43.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 9 | 10 | // a range for to manage the iteration 11 | for (const int(&p)[4] : ia) 12 | for (int q : p) cout << q << " "; 13 | cout << endl; 14 | 15 | // ordinary for loop using subscripts 16 | for (size_t i = 0; i != 3; ++i) 17 | for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; 18 | cout << endl; 19 | 20 | // using pointers. 21 | for (int(*p)[4] = ia; p != ia + 3; ++p) 22 | for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; 23 | cout << endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch03/ex3_44.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 9 | 10 | // a range for to manage the iteration 11 | // use type alias 12 | using int_array = int[4]; 13 | for (int_array& p : ia) 14 | for (int q : p) cout << q << " "; 15 | cout << endl; 16 | 17 | // ordinary for loop using subscripts 18 | for (size_t i = 0; i != 3; ++i) 19 | for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; 20 | cout << endl; 21 | 22 | // using pointers. 23 | // use type alias 24 | for (int_array* p = ia; p != ia + 3; ++p) 25 | for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; 26 | cout << endl; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch03/ex3_45.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; 9 | 10 | // a range for to manage the iteration 11 | for (auto& p : ia) 12 | for (int q : p) cout << q << " "; 13 | cout << endl; 14 | 15 | // ordinary for loop using subscripts 16 | for (size_t i = 0; i != 3; ++i) 17 | for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " "; 18 | cout << endl; 19 | 20 | // using pointers. 21 | for (auto p = ia; p != ia + 3; ++p) 22 | for (int* q = *p; q != *p + 4; ++q) cout << *q << " "; 23 | cout << endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch04/ex4_21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::vector ivec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 7 | for (auto& i : ivec) i = (i % 2) ? (i * 2) : i; 8 | 9 | // Check 10 | for (auto i : ivec) std::cout << i << " "; 11 | std::cout << std::endl; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch04/ex4_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::cin; 5 | using std::endl; 6 | 7 | int main() 8 | { 9 | unsigned grade; 10 | while (cin >> grade) { 11 | // first version(only use conditional operators) 12 | cout << ((grade > 90) ? "high pass" : (grade < 60) 13 | ? "fail" 14 | : (grade < 75) ? "low pass" 15 | : "pass"); 16 | cout << endl; 17 | // second version(only use if statements) 18 | if (grade > 90) 19 | cout << "high pass"; 20 | else if (grade < 60) 21 | cout << "fail"; 22 | else if (grade < 75) 23 | cout << "low pass"; 24 | else 25 | cout << "pass"; 26 | cout << endl; 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch05/ex5_05.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | using std::cin; 10 | 11 | int main() 12 | { 13 | vector scores = {"F", "D", "C", "B", "A", "A++"}; 14 | 15 | int grade{0}; 16 | while (cin >> grade) { 17 | string lettergrade; 18 | if (grade < 60) 19 | lettergrade = scores[0]; 20 | else { 21 | lettergrade = scores[(grade - 50) / 10]; 22 | if (grade != 100) { 23 | if (grade % 10 > 7) 24 | lettergrade += "+"; 25 | else if (grade % 10 < 3) 26 | lettergrade += "-"; 27 | } 28 | } 29 | 30 | cout << lettergrade << endl; 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ch05/ex5_06.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::string; 7 | using std::cout; 8 | using std::endl; 9 | using std::cin; 10 | 11 | int main() 12 | { 13 | vector scores = {"F", "D", "C", "B", "A", "A++"}; 14 | 15 | int grade{0}; 16 | while (cin >> grade) { 17 | string lettergrade = grade < 60 ? scores[0] : scores[(grade - 50) / 10]; 18 | lettergrade += 19 | (grade == 100 || grade < 60) 20 | ? "" 21 | : (grade % 10 > 7) ? "+" : (grade % 10 < 3) ? "-" : ""; 22 | cout << lettergrade << endl; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch05/ex5_09.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | using std::cin; 6 | 7 | int main() 8 | { 9 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0; 10 | char ch; 11 | while (cin >> ch) { 12 | if (ch == 'a') 13 | ++aCnt; 14 | else if (ch == 'e') 15 | ++eCnt; 16 | else if (ch == 'i') 17 | ++iCnt; 18 | else if (ch == 'o') 19 | ++oCnt; 20 | else if (ch == 'u') 21 | ++uCnt; 22 | } 23 | cout << "Number of vowel a: \t" << aCnt << '\n' << "Number of vowel e: \t" 24 | << eCnt << '\n' << "Number of vowel i: \t" << iCnt << '\n' 25 | << "Number of vowel o: \t" << oCnt << '\n' << "Number of vowel u: \t" 26 | << uCnt << endl; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch05/ex5_10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cin; 3 | using std::cout; 4 | using std::endl; 5 | 6 | int main() 7 | { 8 | unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0; 9 | char ch; 10 | while (cin >> ch) switch (ch) { 11 | case 'a': 12 | case 'A': 13 | ++aCnt; 14 | break; 15 | case 'e': 16 | case 'E': 17 | ++eCnt; 18 | break; 19 | case 'i': 20 | case 'I': 21 | ++iCnt; 22 | break; 23 | case 'o': 24 | case 'O': 25 | ++oCnt; 26 | break; 27 | case 'u': 28 | case 'U': 29 | ++uCnt; 30 | break; 31 | } 32 | 33 | cout << "Number of vowel a(A): \t" << aCnt << '\n' 34 | << "Number of vowel e(E): \t" << eCnt << '\n' 35 | << "Number of vowel i(I): \t" << iCnt << '\n' 36 | << "Number of vowel o(O): \t" << oCnt << '\n' 37 | << "Number of vowel u(U): \t" << uCnt << endl; 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /ch05/ex5_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::endl; 6 | using std::vector; 7 | 8 | int main() 9 | { 10 | vector vec1{0, 1, 1, 2}; 11 | vector vec2{0, 1, 1, 2, 3, 5, 8}; 12 | 13 | auto size = vec1.size() < vec2.size() ? vec1.size() : vec2.size(); 14 | for (decltype(vec1.size()) i = 0; i != size; ++i) { 15 | if (vec1[i] != vec2[i]) { 16 | cout << "false" << endl; 17 | return 0; 18 | } 19 | } 20 | cout << "true" << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch05/ex5_19.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::cin; 6 | using std::endl; 7 | using std::string; 8 | 9 | int main() 10 | { 11 | string rsp; 12 | do { 13 | cout << "Input two strings: "; 14 | string str1, str2; 15 | cin >> str1 >> str2; 16 | cout << (str1 <= str2 ? str1 : str2) << " is less than the other. " 17 | << "\n\n" 18 | << "More? Enter yes or no: "; 19 | cin >> rsp; 20 | } while (!rsp.empty() && rsp[0] == 'y'); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch05/ex5_20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::cin; 6 | using std::endl; 7 | using std::string; 8 | 9 | int main() 10 | { 11 | string read, tmp; 12 | while (cin >> read) 13 | if (read == tmp) 14 | break; 15 | else 16 | tmp = read; 17 | 18 | if (cin.eof()) 19 | cout << "no word was repeated." << endl; 20 | else 21 | cout << read << " occurs twice in succession." << endl; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch05/ex5_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(void) 4 | { 5 | int a, b; 6 | std::cin >> a >> b; 7 | std::cout << static_cast(a) / b << std::endl; 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /ch05/ex5_24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | int a, b; 7 | std::cin >> a >> b; 8 | 9 | if (b == 0) throw std::runtime_error("divisor is 0"); 10 | 11 | std::cout << static_cast(a) / b << std::endl; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch05/ex5_25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::cin; 4 | using std::cout; 5 | using std::endl; 6 | using std::runtime_error; 7 | 8 | int main(void) 9 | { 10 | int a, b; 11 | cout << "Input two integers: "; 12 | while (cin >> a >> b) { 13 | try { 14 | if (b == 0) throw runtime_error("divisor is 0"); 15 | cout << static_cast(a) / b << endl; 16 | cout << "Input two integers: "; 17 | } 18 | catch (runtime_error err) { 19 | cout << err.what() ; 20 | cout << "\nTry Again? Enter y or n:" << endl; 21 | char c; 22 | cin >> c; 23 | if (!cin || c == 'n') 24 | break; 25 | } 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch06/Chapter6.h: -------------------------------------------------------------------------------- 1 | int fact(int val); 2 | int func(); 3 | 4 | template T abs(T i) 5 | { 6 | return i >= 0 ? i : -i; 7 | } 8 | -------------------------------------------------------------------------------- /ch06/ex6_10.cpp: -------------------------------------------------------------------------------- 1 | //!@Yue wang 2 | //! 3 | //! Exercise 6.10: 4 | //! Using pointers, write a function to swap the values of two ints. 5 | //! Test the function by calling it and printing the swapped values. 6 | //! 7 | #include 8 | #include 9 | #include 10 | 11 | void swap(int* lhs, int* rhs) 12 | { 13 | int tmp; 14 | tmp = *lhs; 15 | *lhs = *rhs; 16 | *rhs = tmp; 17 | } 18 | 19 | int main() 20 | { 21 | for (int lft, rht; 22 | std::cout << "Please Enter:\n", std::cin >> lft >> rht;) { 23 | swap(&lft, &rht); 24 | std::cout << lft << " " << rht << std::endl; 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /ch06/ex6_11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void reset(int& i) 4 | { 5 | i = 0; 6 | } 7 | 8 | int main() 9 | { 10 | int i = 42; 11 | reset(i); 12 | std::cout << i << std::endl; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /ch06/ex6_12.cpp: -------------------------------------------------------------------------------- 1 | //!@Yue Wang 2 | //! 3 | //! Exercise 6.12: 4 | //! Rewrite the program from exercise 6.10 in § 6.2.1 (p. 210) to use 5 | //! references instead of pointers to swap the value of two ints. Which 6 | //! version do you think would be easier to use and why? 7 | // The version using reference is easier. 8 | //! 9 | #include 10 | #include 11 | 12 | void swap(int& lhs, int& rhs) 13 | { 14 | int temp = lhs; 15 | lhs = rhs; 16 | rhs = temp; 17 | } 18 | 19 | int main() 20 | { 21 | for (int left, right; 22 | std::cout << "Please Enter:\n", std::cin >> left >> right;) { 23 | swap(left, right); 24 | std::cout << left << " " << right << std::endl; 25 | } 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /ch06/ex6_17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | 6 | bool hasUppercase(const string& str) 7 | { 8 | for (auto c : str) 9 | if (isupper(c)) return true; 10 | return false; 11 | } 12 | 13 | const string& makeLowercase(string& str) 14 | { 15 | for (auto& c : str) 16 | if (isupper(c)) c = tolower(c); 17 | return str; 18 | } 19 | 20 | int main() 21 | { 22 | string str("Hello World!"); 23 | std::cout << std::boolalpha << hasUppercase(str) << std::endl; 24 | std::cout << makeLowercase(str) << std::endl; 25 | } 26 | -------------------------------------------------------------------------------- /ch06/ex6_21.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan 2 | //! 3 | //! Exercise 6.21: 4 | //! Write a function that takes an int and a pointer to an int and 5 | //! returns the larger of the int value or the value to which the 6 | //! pointer points. What type should you use for the pointer? 7 | //! 8 | 9 | #include 10 | using std::cout; 11 | 12 | int LargerOne(const int i, const int* ip) 13 | { 14 | return (i > *ip) ? i : *ip; 15 | } 16 | 17 | int main() 18 | { 19 | int c = 6; 20 | cout << LargerOne(7, &c); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch06/ex6_22.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang 2 | //! 3 | //! Exercise 6.22: 4 | //! Write a function to swap two int pointers. 5 | //! 6 | #include 7 | 8 | void swap(int*& lft, int*& rht) 9 | { 10 | auto tmp = lft; 11 | lft = rht; 12 | rht = tmp; 13 | } 14 | 15 | int main() 16 | { 17 | int i = 42, j = 99; 18 | auto lft = &i; 19 | auto rht = &j; 20 | swap(lft, rht); 21 | std::cout << *lft << " " << *rht << std::endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch06/ex6_23.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::cout; 4 | using std::endl; 5 | using std::begin; 6 | using std::end; 7 | 8 | void print(const int* pi) 9 | { 10 | if (pi) cout << *pi << endl; 11 | } 12 | 13 | void print(const char* p) 14 | { 15 | if (p) 16 | while (*p) cout << *p++; 17 | cout << endl; 18 | } 19 | 20 | void print(const int* beg, const int* end) 21 | { 22 | while (beg != end) cout << *beg++ << endl; 23 | } 24 | 25 | void print(const int ia[], size_t size) 26 | { 27 | for (size_t i = 0; i != size; ++i) { 28 | cout << ia[i] << endl; 29 | } 30 | } 31 | 32 | void print(int(&arr)[2]) 33 | { 34 | for (auto i : arr) cout << i << endl; 35 | } 36 | 37 | int main() 38 | { 39 | int i = 0, j[2] = {0, 1}; 40 | char ch[5] = "pezy"; 41 | 42 | print(ch); 43 | print(begin(j), end(j)); 44 | print(&i); 45 | print(j, end(j) - begin(j)); 46 | print(j); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /ch06/ex6_25_26.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang 2 | //! 3 | //! Exercise 6.25: Write a main function that takes two arguments. 4 | //! Concatenate the supplied arguments and print the resulting string. 5 | //! 6 | //! Exercise 6.26: Write a program that accepts the options presented 7 | //! in this section. Print the values of the arguments passed to main. 8 | //! 9 | 10 | #include 11 | #include 12 | 13 | int main(int argc, char** argv) 14 | { 15 | std::string str; 16 | for (int i = 1; i != argc; ++i) { 17 | str += argv[i]; 18 | str += " "; 19 | } 20 | 21 | std::cout << str << std::endl; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ch06/ex6_27.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int sum(std::initializer_list il) 5 | { 6 | int sum = 0; 7 | for (auto i : il) sum += i; 8 | return sum; 9 | } 10 | 11 | int main(void) 12 | { 13 | std::cout << sum({1, 2, 3, 4, 5}) << std::endl; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /ch06/ex6_33.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | using std::cout; 6 | using Iter = vector::iterator; 7 | 8 | void print(Iter beg, Iter end) 9 | { 10 | if (beg != end) { 11 | cout << *beg << " "; 12 | print(std::next(beg), end); 13 | } 14 | } 15 | 16 | int main() 17 | { 18 | vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 19 | print(vec.begin(), vec.end()); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ch06/ex6_42.cpp: -------------------------------------------------------------------------------- 1 | //! @creator by Wang Yue 2 | //! @refactor by pezy 3 | //! 4 | //! @date 27, July. 2015 5 | //! 6 | //! @question 7 | //! Give the second parameter of make_plural (§ 6.3.2, p. 224) a default 8 | //! argument of 's'. Test your program by printing singular and plural versions 9 | //! of the words success and failure. 10 | //! 11 | 12 | #include 13 | #include 14 | 15 | using std::string; 16 | using std::cout; 17 | using std::endl; 18 | 19 | string make_plural(size_t ctr, const string& word, const string& ending = "s") 20 | { 21 | return (ctr > 1) ? word + ending : word; 22 | } 23 | 24 | int main() 25 | { 26 | cout << "singual: " << make_plural(1, "success", "es") << " " 27 | << make_plural(1, "failure") << endl; 28 | cout << "plural : " << make_plural(2, "success", "es") << " " 29 | << make_plural(2, "failure") << endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch06/ex6_44.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan 2 | //! 3 | //! Exercise 6.44: Rewrite the isShorter function from § 6.2.2 (p. 211) to be 4 | //! inline. 5 | //! 6 | 7 | #include 8 | #include 9 | 10 | using std::string; 11 | 12 | inline bool isShorter(const string& s1, const string& s2) 13 | { 14 | return s1.size() < s2.size(); 15 | } 16 | 17 | int main() 18 | { 19 | std::cout << isShorter("pezy", "mooophy") << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /ch06/ex6_47.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // Test 4 | // 5 | // Created by pezy on 14/10/30. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | using std::vector; 12 | using std::cout; 13 | using std::endl; 14 | 15 | //#define NDEBUG 16 | 17 | void printVec(vector& vec) 18 | { 19 | #ifndef NDEBUG 20 | cout << "vector size: " << vec.size() << endl; 21 | #endif 22 | if (!vec.empty()) { 23 | auto tmp = vec.back(); 24 | vec.pop_back(); 25 | printVec(vec); 26 | cout << tmp << " "; 27 | } 28 | } 29 | 30 | int main() 31 | { 32 | vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9}; 33 | printVec(vec); 34 | cout << endl; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /ch06/ex6_51.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; 3 | using std::endl; 4 | 5 | void f() 6 | { 7 | cout << "f()" << endl; 8 | } 9 | 10 | void f(int) 11 | { 12 | cout << "f(int)" << endl; 13 | } 14 | 15 | void f(int, int) 16 | { 17 | cout << "f(int, int)" << endl; 18 | } 19 | 20 | void f(double, double) 21 | { 22 | cout << "f(double, double)" << endl; 23 | } 24 | 25 | int main() 26 | { 27 | f(2.56, 42); // error: 'f' is ambiguous. 28 | f(42); 29 | f(42, 0); 30 | f(2.56, 3.14); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch06/fact.cc: -------------------------------------------------------------------------------- 1 | #include "Chapter6.h" 2 | #include 3 | 4 | int fact(int val) 5 | { 6 | if (val == 0 || val == 1) 7 | return 1; 8 | else 9 | return val * fact(val - 1); 10 | } 11 | 12 | int func() 13 | { 14 | int n, ret = 1; 15 | std::cout << "input a number: "; 16 | std::cin >> n; 17 | while (n > 1) ret *= n--; 18 | return ret; 19 | } 20 | -------------------------------------------------------------------------------- /ch06/factMain.cc: -------------------------------------------------------------------------------- 1 | #include "Chapter6.h" 2 | #include 3 | 4 | int main() 5 | { 6 | std::cout << "5! is " << fact(5) << std::endl; 7 | std::cout << func() << std::endl; 8 | std::cout << abs(-9.78) << std::endl; 9 | } 10 | -------------------------------------------------------------------------------- /ch07/ex7_02.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_02.h 3 | // Exercise 7.2 4 | // 5 | // Created by pezy on 14/11/8. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_02_h 10 | #define CP5_ex7_02_h 11 | 12 | #include 13 | 14 | struct Sales_data { 15 | std::string isbn() const { return bookNo; }; 16 | Sales_data& combine(const Sales_data&); 17 | 18 | std::string bookNo; 19 | unsigned units_sold = 0; 20 | double revenue = 0.0; 21 | }; 22 | 23 | Sales_data& Sales_data::combine(const Sales_data& rhs) 24 | { 25 | units_sold += rhs.units_sold; 26 | revenue += rhs.revenue; 27 | return *this; 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ch07/ex7_03.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_03.cpp 3 | // Exercise 7.03 4 | // 5 | // Created by pezy on 14/11/8. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex7_02.h" 10 | #include 11 | using std::cin; 12 | using std::cout; 13 | using std::endl; 14 | 15 | int main() 16 | { 17 | Sales_data total; 18 | if (cin >> total.bookNo >> total.units_sold >> total.revenue) { 19 | Sales_data trans; 20 | while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue) { 21 | if (total.isbn() == trans.isbn()) 22 | total.combine(trans); 23 | else { 24 | cout << total.bookNo << " " << total.units_sold << " " 25 | << total.revenue << endl; 26 | total = trans; 27 | } 28 | } 29 | cout << total.bookNo << " " << total.units_sold << " " << total.revenue 30 | << endl; 31 | } 32 | else { 33 | std::cerr << "No data?!" << std::endl; 34 | return -1; 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch07/ex7_04.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_04.h 3 | // Exercise 7.4 4 | // 5 | // Created by pezy on 14/11/8. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_04_h 10 | #define CP5_ex7_04_h 11 | 12 | #include 13 | 14 | class Person { 15 | std::string name; 16 | std::string address; 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /ch07/ex7_05.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_05.h 3 | // Exercise 7.5 4 | // 5 | // Created by pezy on 14/11/8. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_05_h 10 | #define CP5_ex7_05_h 11 | 12 | #include 13 | 14 | class Person { 15 | std::string name; 16 | std::string address; 17 | 18 | public: 19 | const std::string& getName() const { return name; } 20 | const std::string& getAddress() const { return address; } 21 | }; 22 | 23 | #endif 24 | 25 | // Should these functions be const? 26 | 27 | // Yes, A const following the parameter list indicates that this is a pointer to 28 | // const. 29 | // These functions my read but not write to the data members of the objects on 30 | // which it is called. 31 | -------------------------------------------------------------------------------- /ch07/ex7_07.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_07.cpp 3 | // Exercise 7.7 4 | // 5 | // Created by pezy on 11/8/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex7_06.h" 10 | 11 | int main() 12 | { 13 | Sales_data total; 14 | if (read(std::cin, total)) { 15 | Sales_data trans; 16 | while (read(std::cin, trans)) { 17 | if (total.isbn() == trans.isbn()) 18 | total.combine(trans); 19 | else { 20 | print(std::cout, total) << std::endl; 21 | total = trans; 22 | } 23 | } 24 | print(std::cout, total) << std::endl; 25 | } 26 | else { 27 | std::cerr << "No data?!" << std::endl; 28 | return -1; 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch07/ex7_09.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_09.h 3 | // Exercise 7.9 4 | // 5 | // Created by pezy on 11/8/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_09_h 10 | #define CP5_ex7_09_h 11 | 12 | #include 13 | #include 14 | 15 | struct Person { 16 | const std::string& getName() const { return name; } 17 | const std::string& getAddress() const { return address; } 18 | 19 | std::string name; 20 | std::string address; 21 | }; 22 | 23 | std::istream& read(std::istream& is, Person& person) 24 | { 25 | is >> person.name >> person.address; 26 | if (!is) person = Person(); 27 | return is; 28 | } 29 | 30 | std::ostream& print(std::ostream& os, const Person& person) 31 | { 32 | os << person.name << " " << person.address; 33 | return os; 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /ch07/ex7_11.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_11.cpp 3 | // Exercise 7.11 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex7_11.h" 10 | 11 | int main() 12 | { 13 | Sales_data item1; 14 | print(std::cout, item1) << std::endl; 15 | 16 | Sales_data item2("0-201-78345-X"); 17 | print(std::cout, item2) << std::endl; 18 | 19 | Sales_data item3("0-201-78345-X", 3, 20.00); 20 | print(std::cout, item3) << std::endl; 21 | 22 | Sales_data item4(std::cin); 23 | print(std::cout, item4) << std::endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch07/ex7_13.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_13.cpp 3 | // Exercise 7.13 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex7_12.h" 10 | 11 | int main() 12 | { 13 | Sales_data total(std::cin); 14 | if (!total.isbn().empty()) { 15 | std::istream& is = std::cin; 16 | while (is) { 17 | Sales_data trans(is); 18 | if (total.isbn() == trans.isbn()) 19 | total.combine(trans); 20 | else { 21 | print(std::cout, total) << std::endl; 22 | total = trans; 23 | } 24 | } 25 | } 26 | else { 27 | std::cerr << "No data?!" << std::endl; 28 | return -1; 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch07/ex7_23.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_23.h 3 | // Exercise 7.23 4 | // 5 | // Created by pezy on 11/14/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_23_h 10 | #define CP5_ex7_23_h 11 | 12 | #include 13 | 14 | class Screen { 15 | public: 16 | using pos = std::string::size_type; 17 | 18 | Screen() = default; 19 | Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) 20 | { 21 | } 22 | 23 | char get() const { return contents[cursor]; } 24 | char get(pos r, pos c) const { return contents[r * width + c]; } 25 | 26 | private: 27 | pos cursor = 0; 28 | pos height = 0, width = 0; 29 | std::string contents; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /ch07/ex7_24.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_24.cpp 3 | // Exercise 7.24 4 | // 5 | // Created by pezy on 11/14/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_24_h 10 | #define CP5_ex7_24_h 11 | 12 | #include 13 | 14 | class Screen { 15 | public: 16 | using pos = std::string::size_type; 17 | 18 | Screen() = default; // 1 19 | Screen(pos ht, pos wd) : height(ht), width(wd), contents(ht * wd, ' ') {} // 2 20 | Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c) 21 | { 22 | } // 3 23 | 24 | char get() const { return contents[cursor]; } 25 | char get(pos r, pos c) const { return contents[r * width + c]; } 26 | 27 | private: 28 | pos cursor = 0; 29 | pos height = 0, width = 0; 30 | std::string contents; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /ch07/ex7_26.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_26.cpp 3 | // Exercise 7.26 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief implementation of class Sales_data 9 | // @See ex7_26.h 10 | 11 | #include "ex7_26.h" 12 | 13 | // member functions. 14 | Sales_data& Sales_data::combine(const Sales_data& rhs) 15 | { 16 | units_sold += rhs.units_sold; 17 | revenue += rhs.revenue; 18 | return *this; 19 | } 20 | 21 | // friend functions 22 | std::istream& read(std::istream& is, Sales_data& item) 23 | { 24 | double price = 0; 25 | is >> item.bookNo >> item.units_sold >> price; 26 | item.revenue = price * item.units_sold; 27 | return is; 28 | } 29 | 30 | std::ostream& print(std::ostream& os, const Sales_data& item) 31 | { 32 | os << item.isbn() << " " << item.units_sold << " " << item.revenue; 33 | return os; 34 | } 35 | 36 | Sales_data add(const Sales_data& lhs, const Sales_data& rhs) 37 | { 38 | Sales_data sum = lhs; 39 | sum.combine(rhs); 40 | return sum; 41 | } 42 | -------------------------------------------------------------------------------- /ch07/ex7_27_TEST.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_27_TEST.cpp 3 | // Test of Exercise 7.27 4 | // 5 | // Created by pezy on 11/14/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex7_27.h" 10 | 11 | int main() 12 | { 13 | Screen myScreen(5, 5, 'X'); 14 | myScreen.move(4, 0).set('#').display(std::cout); 15 | std::cout << "\n"; 16 | myScreen.display(std::cout); 17 | std::cout << "\n"; 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch07/ex7_31.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_31.h 3 | // Exercise 7.31 4 | // 5 | // Created by pezy on 11/17/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_31_h 10 | #define CP5_ex7_31_h 11 | 12 | class Y; 13 | 14 | class X { 15 | Y* y = nullptr; 16 | }; 17 | 18 | class Y { 19 | X x; 20 | }; 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /ch07/ex7_43.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_43.cpp 3 | // Exercise 7.43 4 | // 5 | // Created by pezy on 11/20/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | class NoDefault { 12 | public: 13 | NoDefault(int i) {} 14 | }; 15 | 16 | class C { 17 | public: 18 | C() : def(0) {} // define the constructor of C. 19 | private: 20 | NoDefault def; 21 | }; 22 | 23 | int main() 24 | { 25 | C c; 26 | 27 | std::vector vec(10); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch07/ex7_53.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_53.h 3 | // Exercise 7.53 4 | // 5 | // Created by pezy on 11/25/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_53_h 10 | #define CP5_ex7_53_h 11 | 12 | class Debug { 13 | public: 14 | constexpr Debug(bool b = true) : rt(b), io(b), other(b) {} 15 | constexpr Debug(bool r, bool i, bool o) : rt(r), io(i), other(0) {} 16 | constexpr bool any() { return rt || io || other; } 17 | 18 | void set_rt(bool b) { rt = b; } 19 | void set_io(bool b) { io = b; } 20 | void set_other(bool b) { other = b; } 21 | 22 | private: 23 | bool rt; // runtime error 24 | bool io; // I/O error 25 | bool other; // the others 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /ch07/ex7_57.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex7_57.h 3 | // Exercise 7.57 4 | // 5 | // Created by pezy on 11/25/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | 9 | #ifndef CP5_ex7_57_h 10 | #define CP5_ex7_57_h 11 | 12 | #include 13 | 14 | class Account { 15 | public: 16 | void calculate() { amount += amount * interestRate; } 17 | static double rate() { return interestRate; } 18 | static void rate(double newRate) { interestRate = newRate; } 19 | 20 | private: 21 | std::string owner; 22 | double amount; 23 | static double interestRate; 24 | static constexpr double todayRate = 42.42; 25 | static double initRate() { return todayRate; } 26 | }; 27 | 28 | double Account::interestRate = initRate(); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ch08/ex8_02.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_02.cpp 3 | // Exercise 8.2 4 | // 5 | // Created by pezy on 11/27/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Test your function by calling it, passing cin as an argument 9 | 10 | #include 11 | using std::istream; 12 | 13 | istream& func(istream& is) 14 | { 15 | std::string buf; 16 | while (is >> buf) std::cout << buf << std::endl; 17 | is.clear(); 18 | return is; 19 | } 20 | 21 | int main() 22 | { 23 | istream& is = func(std::cin); 24 | std::cout << is.rdstate() << std::endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /ch08/ex8_04.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_04.cpp 3 | // Exercise 8.4 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a function to open a file for input and read its contents into 9 | // a vector of strings, 10 | // storing each line as a separate element in the vector. 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using std::vector; 18 | using std::string; 19 | using std::ifstream; 20 | using std::cout; 21 | using std::endl; 22 | 23 | void ReadFileToVec(const string& fileName, vector& vec) 24 | { 25 | ifstream ifs(fileName); 26 | if (ifs) { 27 | string buf; 28 | while (std::getline(ifs, buf)) vec.push_back(buf); 29 | } 30 | } 31 | 32 | int main() 33 | { 34 | vector vec; 35 | ReadFileToVec("../data/book.txt", vec); 36 | for (const auto& str : vec) cout << str << endl; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch08/ex8_05.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_05.cpp 3 | // Exercise 8.5 4 | // 5 | // Created by pezy on 11/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the previous program to store each word in a separate 9 | // element. 10 | // @See ex8_04.cpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using std::vector; 18 | using std::string; 19 | using std::ifstream; 20 | using std::cout; 21 | using std::endl; 22 | 23 | void ReadFileToVec(const string& fileName, vector& vec) 24 | { 25 | ifstream ifs(fileName); 26 | if (ifs) { 27 | string buf; 28 | while (ifs >> buf) vec.push_back(buf); 29 | } 30 | } 31 | 32 | int main() 33 | { 34 | vector vec; 35 | ReadFileToVec("../data/book.txt", vec); 36 | for (const auto& str : vec) cout << str << endl; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch08/ex8_06.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yogykwan/cpp-primer-workbook/fe1277a4be14ea6517e8d6a255ab25b5125fe2b7/ch08/ex8_06.cpp -------------------------------------------------------------------------------- /ch08/ex8_09.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex8_09.cpp 3 | // Exercise 8.9 4 | // 5 | // Created by pezy on 11/29/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Use the function you wrote for the first exercise in § 8.1.2 (p.314) 9 | // to print the contents of an istringstream object. 10 | // @See Exercise 8.1 11 | 12 | #include 13 | #include 14 | using std::istream; 15 | 16 | istream& func(istream& is) 17 | { 18 | std::string buf; 19 | while (is >> buf) std::cout << buf << std::endl; 20 | is.clear(); 21 | return is; 22 | } 23 | 24 | int main() 25 | { 26 | std::istringstream iss("hello"); 27 | func(iss); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch09/ex9_13.cpp: -------------------------------------------------------------------------------- 1 | //! @author @shbling @Alan 2 | //! 3 | //! Exercise 9.13: 4 | //! How would you initialize a vector from a list? 5 | //! From a vector? 6 | //! Write code to check your answers. 7 | //! 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using std::list; 14 | using std::vector; 15 | using std::cout; 16 | using std::endl; 17 | 18 | int main() 19 | { 20 | list ilst(5, 4); 21 | vector ivc(5, 5); 22 | 23 | //! from list to vector 24 | vector dvc(ilst.begin(), ilst.end()); 25 | for (auto i : ilst) cout << i; 26 | cout << endl; 27 | for (auto t : dvc) cout << t; 28 | cout << endl; 29 | 30 | //! from vector to vector 31 | vector dvc2(ivc.begin(), ivc.end()); 32 | for (auto i : ivc) cout << i; 33 | cout << endl; 34 | for (auto t : dvc2) cout << t; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /ch09/ex9_14.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan @pezy 2 | //! 3 | //! Exercise 9.14: 4 | //! Write a program to assign the elements from a list of char* pointers 5 | //! to C-style character strings 6 | //! 7 | //! @Notice C-style character strings should use const char*, otherwise warning. 8 | //! 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main() 16 | { 17 | std::list l{"Mooophy", "pezy", "Queeuqueg"}; 18 | std::vector v; 19 | v.assign(l.cbegin(), l.cend()); 20 | 21 | for (const auto& ch : v) std::cout << ch << std::endl; 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /ch09/ex9_15.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.15 2 | //! @author pezy 3 | //! @date 2014-12-02 4 | //! @Brief Write a program to determine whether two vectors are equal. 5 | 6 | #include 7 | #include 8 | 9 | int main() 10 | { 11 | std::vector vec1{1, 2, 3, 4, 5}; 12 | std::vector vec2{1, 2, 3, 4, 5}; 13 | std::vector vec3{1, 2, 3, 4}; 14 | 15 | std::cout << std::boolalpha << (vec1 == vec2) << std::endl; 16 | std::cout << std::boolalpha << (vec1 == vec3) << std::endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ch09/ex9_16.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.16 2 | //! @author pezy 3 | //! @date 2014-12-02 4 | //! @Brief Repeat the previous program, but compare elements in a list to 5 | //! a vector. 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | std::list list{1, 2, 3, 4, 5}; 14 | std::vector vec1{1, 2, 3, 4, 5}; 15 | std::vector vec2{1, 2, 3, 4}; 16 | 17 | std::cout << std::boolalpha 18 | << (std::vector(list.begin(), list.end()) == vec1) 19 | << std::endl; 20 | std::cout << std::boolalpha 21 | << (std::vector(list.begin(), list.end()) == vec2) 22 | << std::endl; 23 | } 24 | -------------------------------------------------------------------------------- /ch09/ex9_18.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_18.cpp 3 | // Exercise 9.18 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a program to read a sequence of strings from the standard 9 | // input into 10 | // a deque. Use iterators to write a loop to print the elements in the 11 | // deque. 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | using std::string; 18 | using std::deque; 19 | using std::cout; 20 | using std::cin; 21 | using std::endl; 22 | 23 | int main() 24 | { 25 | deque input; 26 | for (string str; cin >> str; input.push_back(str)) 27 | ; 28 | for (auto iter = input.cbegin(); iter != input.cend(); ++iter) 29 | cout << *iter << endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch09/ex9_19.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_19.cpp 3 | // Exercise 9.19 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the program from the previous exercise to use a list. 9 | // List the changes you needed to make. 10 | // @See ex9_18.cpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using std::string; 17 | using std::list; 18 | using std::cout; 19 | using std::cin; 20 | using std::endl; 21 | 22 | int main() 23 | { 24 | list input; 25 | for (string str; cin >> str; input.push_back(str)) 26 | ; 27 | for (auto iter = input.cbegin(); iter != input.cend(); ++iter) 28 | cout << *iter << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch09/ex9_20.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_20.cpp 3 | // Exercise 9.20 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a program to copy elements from a list into two deques. 9 | // The even-valued elements should go into one deque and the odd ones 10 | // into the other. 11 | 12 | #include 13 | #include 14 | #include 15 | using std::deque; 16 | using std::list; 17 | using std::cout; 18 | using std::cin; 19 | using std::endl; 20 | 21 | int main() 22 | { 23 | list l{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 24 | deque odd, even; 25 | for (auto i : l) (i & 0x1 ? odd : even).push_back(i); 26 | 27 | for (auto i : odd) cout << i << " "; 28 | cout << endl; 29 | for (auto i : even) cout << i << " "; 30 | cout << endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch09/ex9_22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector; 4 | 5 | void insertDoubleValue(vector& iv, int some_val) 6 | { 7 | auto cursor = iv.size() / 2; 8 | auto iter = iv.begin(), mid = iv.begin() + cursor; 9 | while (iter != mid) { 10 | if (*iter == some_val) { 11 | iter = iv.insert(iter, 2 * some_val); 12 | ++iter; 13 | ++cursor; 14 | mid = iv.begin() + cursor; 15 | } 16 | ++iter; 17 | } 18 | } 19 | 20 | void print(const vector& iv) 21 | { 22 | for (auto i : iv) std::cout << i << " "; 23 | std::cout << std::endl; 24 | } 25 | 26 | int main() 27 | { 28 | vector iv = {1, 1, 1, 1, 1, 7, 1, 9}; 29 | insertDoubleValue(iv, 1); 30 | print(iv); 31 | } 32 | -------------------------------------------------------------------------------- /ch09/ex9_24.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang @pezy 2 | //! 3 | //! Exercise 9.24: 4 | //! Write a program that fetches the first element in a vector using at, 5 | //! the subscript operator, front, and begin. Test your program on an empty 6 | //! vector. 7 | //! 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | std::vector v; 14 | std::cout << v.at( 15 | 0); // terminating with uncaught exception of type std::out_of_range 16 | std::cout << v[0]; // Segmentation fault: 11 17 | std::cout << v.front(); // Segmentation fault: 11 18 | std::cout << *v.begin(); // Segmentation fault: 11 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch09/ex9_27.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.27 2 | //! @author pezy 3 | //! @date 2014-12-03 4 | //! @Brief Write a program to find and remove the odd-valued elements in a 5 | //! forward_list. 6 | 7 | #include 8 | #include 9 | 10 | using std::forward_list; 11 | using std::cout; 12 | using std::endl; 13 | 14 | int main() 15 | { 16 | forward_list flst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 17 | for (auto prev = flst.before_begin(), curr = flst.begin(); 18 | curr != flst.end();) 19 | if (*curr & 0x1) 20 | curr = flst.erase_after(prev); 21 | else 22 | prev = curr++; 23 | 24 | for (auto i : flst) cout << i << " "; 25 | cout << endl; 26 | } 27 | -------------------------------------------------------------------------------- /ch09/ex9_31_1.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_31.cpp 3 | // Exercise 9.31 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief The program on page 354 to remove even-valued elements and 9 | // duplicate odd ones will not work on a list or forward_list. Why? 10 | // Revise the program so that it works on these types as well. 11 | // @list iter += 2; -> advance(iter, 2); 12 | // 13 | 14 | #include 15 | #include 16 | 17 | using std::list; 18 | using std::cout; 19 | using std::endl; 20 | using std::advance; 21 | 22 | int main() 23 | { 24 | list vi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 25 | auto iter = vi.begin(); 26 | while (iter != vi.end()) { 27 | if (*iter % 2) { 28 | iter = vi.insert(iter, *iter); 29 | advance(iter, 2); 30 | } 31 | else 32 | iter = vi.erase(iter); 33 | } 34 | 35 | for (auto i : vi) cout << i << " "; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /ch09/ex9_33.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_33.cpp 3 | // Exercise 9.33 4 | // 5 | // Created by pezy on 12/3/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief In the final example in this section what would happen 9 | // if we did not assign the result of insert to begin? 10 | // Write a program that omits this assignment to see if your 11 | // expectation was correct. 12 | // @Answer crash, cause the iterator is invalid after insert. Because 13 | // Iterators, pointers, and references to a 14 | // vector or string are invalid if the container was reallocated. 15 | 16 | #include 17 | #include 18 | 19 | using std::vector; 20 | using std::cout; 21 | using std::endl; 22 | 23 | int main() 24 | { 25 | vector v{1, 2, 3, 4, 5, 6, 7, 8, 9}; 26 | auto begin = v.begin(); 27 | while (begin != v.end()) { 28 | ++begin; 29 | /*begin = */ v.insert(begin, 42); 30 | ++begin; 31 | } 32 | 33 | for (auto i : v) cout << i << " "; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch09/ex9_38.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan 2 | //! 3 | //! Exercise 9.38: 4 | //! Write a program to explore how vectors grow in the library you use. 5 | //! 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | std::vector v; 14 | std::string word; 15 | 16 | while (std::cin >> word) { 17 | v.push_back(word); 18 | std::cout << v.capacity() << "\n"; 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /ch09/ex9_41.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_41.cpp 3 | // Exercise 9.41 4 | // 5 | // Created by pezy on 12/4/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Write a program that initializes a string from a vector. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using std::vector; 15 | using std::cout; 16 | using std::endl; 17 | using std::string; 18 | 19 | int main() 20 | { 21 | vector vec{'p', 'e', 'z', 'y'}; 22 | string str(vec.begin(), vec.end()); 23 | 24 | cout << str << endl; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /ch09/ex9_44.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_44.cpp 3 | // Exercise 9.44 4 | // 5 | // Created by pezy on 12/4/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the previous function using an index and replace. 9 | // @See 9.43 10 | 11 | #include 12 | #include 13 | 14 | using std::cout; 15 | using std::endl; 16 | using std::string; 17 | using std::prev; 18 | 19 | void Replace(string& s, string const& oldVal, string const& newVal) 20 | { 21 | for (string::size_type i = 0; i != s.size(); ++i) 22 | if (s.substr(i, oldVal.size()) == oldVal) { 23 | s.replace(i, oldVal.size(), newVal); 24 | i += newVal.size() - 1; 25 | } 26 | } 27 | 28 | int main() 29 | { 30 | string str{"To drive straight thru is a foolish, tho courageous act."}; 31 | Replace(str, "tho", "though"); 32 | Replace(str, "thru", "through"); 33 | cout << str << endl; 34 | } 35 | -------------------------------------------------------------------------------- /ch09/ex9_46.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex9_46.cpp 3 | // Exercise 9.46 4 | // 5 | // Created by pezy on 12/5/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the previous exercise using a position and length to manage 9 | // the strings. 10 | // This time use only the insert function. 11 | // @See 9.45 12 | 13 | #include 14 | #include 15 | 16 | std::string pre_suffix(const std::string& name, const std::string& pre, 17 | const std::string& su) 18 | { 19 | std::string ret(name); 20 | ret.insert(0, pre); 21 | ret.insert(ret.size(), su); 22 | 23 | return ret; 24 | } 25 | 26 | int main() 27 | { 28 | std::string name("alan"); 29 | std::cout << pre_suffix(name, "Mr.", ",Jr."); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch09/ex9_49.cpp: -------------------------------------------------------------------------------- 1 | //! @file Exercise 9.49 2 | //! @author pezy 3 | //! @date 2014-12-05 4 | //! @Brief A letter has an ascender if, as with d or f, part of the letter 5 | //! extends above the middle of the line. 6 | // A letter has a descender if, as with p or g, part of the letter 7 | // extends below the line. 8 | // Write a program that reads a file containing words and reports the 9 | // longest word that contains 10 | // neither ascenders nor descenders. 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using std::string; 17 | using std::ifstream; 18 | using std::cout; 19 | using std::endl; 20 | 21 | int main() 22 | { 23 | ifstream ifs("../data/letter.txt"); 24 | if (!ifs) return -1; 25 | string longest_word; 26 | for (string word; ifs >> word;) 27 | if (word.find_first_not_of("aceimnorsuvwxz") == string::npos && 28 | word.size() > longest_word.size()) 29 | longest_word = word; 30 | 31 | cout << longest_word << endl; 32 | } 33 | -------------------------------------------------------------------------------- /ch09/ex9_50.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang 2 | //! 3 | //! Exercise 9.50: 4 | //! Write a program to process a vectors whose elements represent 5 | //! integral values. 6 | //! Produce the sum of all the elements in that vector. 7 | //! Change the program so that it sums of strings that represent floating-point 8 | //! values. 9 | //! 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | int sum_for_int(const std::vector &v) 16 | { 17 | int sum = 0; 18 | for (auto const& s : v) sum += std::stoi(s); 19 | return sum; 20 | } 21 | 22 | float sum_for_float(const std::vector &v) 23 | { 24 | float sum = 0.0; 25 | for (auto const& s : v) sum += std::stof(s); 26 | return sum; 27 | } 28 | 29 | int main() 30 | { 31 | std::vector v = {"1", "2", "3", "4.5"}; 32 | std::cout << sum_for_int(v) << std::endl; 33 | std::cout << sum_for_float(v) << std::endl; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /ch10/ex10_06.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_06.cpp 3 | // Exercise 10.6 4 | // 5 | // Created by pezy on 12/9/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Using fill_n, write a program to set a sequence of int values to 0. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using std::vector; 15 | using std::cout; 16 | using std::endl; 17 | using std::fill_n; 18 | 19 | int main() 20 | { 21 | vector vec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 22 | fill_n(vec.begin(), vec.size(), 0); 23 | 24 | for (auto i : vec) cout << i << " "; 25 | cout << endl; 26 | } 27 | 28 | // @Output 29 | // 0 0 0 0 0 0 0 0 0 0 -------------------------------------------------------------------------------- /ch10/ex10_12.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang 2 | //! Exercise 10.12: 3 | //! Write a function named compareIsbn that compares the isbn() members of two 4 | //! Sales_data objects. 5 | //! Use that function to sort a vector that holds Sales_data objects. 6 | //! 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "../ch07/ex7_26.h" // Sales_data class. 14 | 15 | inline bool compareIsbn(const Sales_data& sd1, const Sales_data& sd2) 16 | { 17 | return sd1.isbn().size() < sd2.isbn().size(); 18 | } 19 | 20 | int main() 21 | { 22 | Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz"); 23 | std::vector v{d1, d2, d3, d4, d5}; 24 | 25 | //! @note the elements the iterators pointing to 26 | //! must match the parameters of the predicate. 27 | std::sort(v.begin(), v.end(), compareIsbn); 28 | 29 | for (const auto& element : v) std::cout << element.isbn() << " "; 30 | std::cout << std::endl; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ch10/ex10_17.cpp: -------------------------------------------------------------------------------- 1 | //! @pezy 2 | //! 3 | //! Exercise 10.17 4 | //! Rewrite exercise 10.12 from 10.3.1 (p. 387) 5 | //! to use a lambda in the call to sort instead of the compareIsbn function. 6 | //! 7 | //! @See 7.26, 10.12 8 | 9 | #include "../ch07/ex7_26.h" // Sales_data class. 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main() 16 | { 17 | Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz"); 18 | std::vector v{d1, d2, d3, d4, d5}; 19 | 20 | std::sort(v.begin(), v.end(), 21 | [](const Sales_data& sd1, const Sales_data& sd2) { 22 | return sd1.isbn().size() < sd2.isbn().size(); 23 | }); 24 | 25 | for (const auto& element : v) std::cout << element.isbn() << " "; 26 | std::cout << std::endl; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ch10/ex10_21.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | * @question: 3 | * Write a lambda that captures a local `int` variable and 4 | * decrements that variable until it reaches 0. 5 | * Once the variable is 0 additional calls should 6 | * no longer decrement the variable. 7 | * The lambda should return a `bool` that indicates 8 | * whether the captured variable is 0. 9 | * @author: pezy 10 | * @date: 2016-07-01 11 | * @see: 12 | */ 13 | 14 | #include 15 | 16 | using std::cout; 17 | using std::endl; 18 | 19 | int main() 20 | { 21 | // local int variable 22 | int local_val = 7; 23 | auto decrement_to_zero = [&local_val]() { 24 | if (local_val == 0) 25 | return true; 26 | else { 27 | --local_val; 28 | return false; 29 | } 30 | }; 31 | 32 | while (!decrement_to_zero()) cout << local_val << endl; 33 | } 34 | -------------------------------------------------------------------------------- /ch10/ex10_22.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_22.cpp 3 | // Exercise 10.22 4 | // 5 | // Created by pezy on 12/11/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // @Brief Rewrite the program to count words of size 6 or less using 9 | // functions in place of the lambdas. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using std::string; 18 | using namespace std::placeholders; 19 | 20 | bool isBiggerThan6(const string& s, string::size_type sz) 21 | { 22 | return s.size() > sz; 23 | } 24 | 25 | int main() 26 | { 27 | std::vector authors{"Mooophy", "pezy", "Queequeg90", "shbling", 28 | "evan617"}; 29 | std::cout << count_if(authors.cbegin(), authors.cend(), 30 | bind(isBiggerThan6, _1, 6)); 31 | } 32 | 33 | // @Out 34 | // 4 -------------------------------------------------------------------------------- /ch10/ex10_27.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_27.cpp 3 | // Exercise 10.27 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // In addition to unique, the library defines function named unique_copy that 9 | // takes a third iterator denoting a destination into which to copy the unique 10 | // elements. 11 | // Write a program that uses unique_copy to copy the unique elements from 12 | // a vector into an initially empty list. 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int main() 20 | { 21 | std::vector vec{3, 5, 1, 5, 1, 7, 3, 7, 9}; 22 | std::list lst; 23 | 24 | std::sort(vec.begin(), vec.end()); 25 | std::unique_copy(vec.begin(), vec.end(), back_inserter(lst)); 26 | for (auto i : lst) std::cout << i << " "; 27 | std::cout << std::endl; 28 | } 29 | -------------------------------------------------------------------------------- /ch10/ex10_29.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_29.cpp 3 | // Exercise 10.29 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write a program using stream iterators to read a text file into a vector of 9 | // strings. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using std::string; 18 | 19 | int main() 20 | { 21 | std::ifstream ifs("../data/book.txt"); 22 | std::istream_iterator in(ifs), eof; 23 | std::vector vec; 24 | std::copy(in, eof, back_inserter(vec)); 25 | 26 | // output 27 | std::copy(vec.cbegin(), vec.cend(), 28 | std::ostream_iterator(std::cout, "\n")); 29 | } 30 | -------------------------------------------------------------------------------- /ch10/ex10_30.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_30.cpp 3 | // Exercise 10.30 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Use stream iterators, sort, and copy to read a sequence of integers from the 9 | // standard input, 10 | // sort them, and then write them back to the standard output. 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | std::istream_iterator in_iter(std::cin), eof; 20 | std::vector vec; 21 | while (in_iter != eof) vec.push_back(*in_iter++); 22 | std::sort(vec.begin(), vec.end()); 23 | std::copy(vec.cbegin(), vec.cend(), 24 | std::ostream_iterator(std::cout, " ")); 25 | } -------------------------------------------------------------------------------- /ch10/ex10_31.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex10_31.cpp 3 | // Exercise 10.31 4 | // 5 | // Created by pezy on 12/13/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Update the program from the previous exercise so that it prints only the 9 | // unique elements. 10 | // Your program should use unqiue_copy 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | std::istream_iterator in_iter(std::cin), eof; 20 | std::vector vec; 21 | while (in_iter != eof) vec.push_back(*in_iter++); 22 | std::sort(vec.begin(), vec.end()); 23 | std::unique_copy(vec.cbegin(), vec.cend(), 24 | std::ostream_iterator(std::cout, " ")); 25 | } -------------------------------------------------------------------------------- /ch10/ex10_42.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan @pezy 2 | //! 3 | //! Exercise 10.42: 4 | //! Reimplement the program that eliminated duplicate words that 5 | //! we wrote in § 10.2.3 (p. 383) to use a list instead of a vector. 6 | //! 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using std::string; 13 | using std::list; 14 | 15 | void elimDups(list& words) 16 | { 17 | words.sort(); 18 | words.unique(); 19 | } 20 | 21 | int main() 22 | { 23 | list l = {"aa", "aa", "aa", "aa", "aasss", "aa"}; 24 | elimDups(l); 25 | for (const auto& e : l) std::cout << e << " "; 26 | std::cout << std::endl; 27 | } 28 | 29 | //! output 30 | //! 31 | // aa aasss 32 | -------------------------------------------------------------------------------- /ch11/ex11_11.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex11_11.cpp 3 | // Exercise 11.11 4 | // 5 | // Created by pezy on 12/15/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Redefine bookstore without using decltype. 9 | 10 | #include "../ch07/ex7_26.h" 11 | #include 12 | 13 | bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs) 14 | { 15 | return lhs.isbn() < rhs.isbn(); 16 | } 17 | 18 | int main() 19 | { 20 | using compareType = bool (*)(const Sales_data& lhs, const Sales_data& rhs); 21 | // typedef bool(*compareType)(const Sales_data &lhs, const Sales_data &rhs); 22 | std::multiset bookstore(compareIsbn); 23 | } -------------------------------------------------------------------------------- /ch11/ex11_18.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan 2 | //! 3 | //! Exercise 11.18: 4 | //! Write the type of map_it from the loop on page 430 without using auto or 5 | //! decltype. 6 | //! 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int main() 13 | { 14 | std::map word_count; 15 | 16 | //! the orignal codes: 17 | // auto map_it = word_count.cbegin(); 18 | 19 | std::map::const_iterator map_it = word_count.cbegin(); 20 | //! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 21 | //! the type ex11.18 required. 22 | 23 | // compare the current iterator to the off-the-end iterator 24 | while (map_it != word_count.cend()) { 25 | // dereference the iterator to print the element key--value pairs 26 | std::cout << map_it->first << " occurs " << map_it->second << " times" 27 | << std::endl; 28 | ++map_it; // increment the iterator to denote the next element 29 | } 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /ch11/ex11_20.cpp: -------------------------------------------------------------------------------- 1 | //! @Alan @pezy 2 | //! 3 | //! Exercise 11.20: 4 | //! Rewrite the word-counting program from § 11.1 (p. 421) to use insert instead 5 | //! of subscripting. Which program do you think is easier to write and read? 6 | //! Explain your reasoning. 7 | //! 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using std::string; 14 | 15 | int main() 16 | { 17 | std::map word_count; 18 | string word; 19 | while (std::cin >> word) { 20 | auto ret = word_count.insert({word, 1}); 21 | if (!ret.second) ++ret.first->second; 22 | } 23 | 24 | //! print the content of the map. 25 | for (const auto& w : word_count) 26 | std::cout << w.first << " " << w.second 27 | << ((w.second > 1) ? " times" : " time") << std::endl; 28 | } 29 | -------------------------------------------------------------------------------- /ch11/ex11_23.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex11_23.cpp 3 | // Exercise 11.23 4 | // 5 | // Created by pezy on 12/16/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Rewrite the map that stored vectors of children’s names with a key that is 9 | // the family last name for the exercises in 11.2.1 (p. 424) to use a multimap. 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using std::string; 16 | 17 | int main() 18 | { 19 | std::multimap families; 20 | for (string lastName, childName; std::cin >> childName >> lastName; 21 | families.emplace(lastName, childName)) 22 | ; 23 | for (const auto& s : families) 24 | std::cout << s.second << " " << s.first << std::endl; 25 | } -------------------------------------------------------------------------------- /ch11/ex11_32.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex11_32.cpp 3 | // Exercise 11.32 4 | // 5 | // Created by pezy on 12/17/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Using the multimap from the previous exercise, write a program to print the 9 | // list of **authors and their works** alphabetically. 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using std::string; 17 | 18 | int main() 19 | { 20 | std::multimap authors{ 21 | {"alan", "DMA"}, {"pezy", "LeetCode"}, {"alan", "CLRS"}, 22 | {"wang", "FTP"}, {"pezy", "CP5"}, {"wang", "CPP-Concurrency"}}; 23 | std::map> order_authors; 24 | for (const auto& author : authors) 25 | order_authors[author.first].insert(author.second); 26 | for (const auto& author : order_authors) { 27 | std::cout << author.first << ": "; 28 | for (const auto& work : author.second) std::cout << work << " "; 29 | std::cout << std::endl; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch12/ex12_02_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex12_02.h" 2 | #include 3 | 4 | int main() 5 | { 6 | const StrBlob csb{"hello", "world", "pezy"}; 7 | StrBlob sb{"hello", "world", "Mooophy"}; 8 | 9 | std::cout << csb.front() << " " << csb.back() << std::endl; 10 | sb.back() = "pezy"; 11 | std::cout << sb.front() << " " << sb.back() << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /ch12/ex12_13.cpp: -------------------------------------------------------------------------------- 1 | //! @Yue Wang 2 | //! 3 | //! ex12.13 What happens if we excute the following code? 4 | //! 5 | // generate a runtime error : double free 6 | //! 7 | 8 | #include 9 | #include 10 | 11 | int main() 12 | { 13 | { 14 | auto sp = std::make_shared(); 15 | auto p = sp.get(); 16 | delete p; 17 | } 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ch12/ex12_16.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_15.cpp 3 | // Exercise 12.15 4 | // 5 | // Created by pezy on 12/22/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Compilers don’t always give easy-to-understand error messages if we attempt 9 | // to 10 | // copy or assign a unique_ptr. Write a program that contains these errors to 11 | // see 12 | // how your compiler diagnoses them. 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | using std::string; 19 | using std::unique_ptr; 20 | 21 | int main() 22 | { 23 | unique_ptr p1(new string("pezy")); 24 | // unique_ptr p2(p1); // copy 25 | // ^ 26 | // Error: Call to implicitly-deleted copy constructor of 27 | // 'unique_ptr' 28 | // 29 | // unique_ptr p3 = p1; // assign 30 | // ^ 31 | // Error: Call to implicitly-deleted copy constructor of 32 | // 'unique_ptr' 33 | std::cout << *p1 << std::endl; 34 | p1.reset(nullptr); 35 | } -------------------------------------------------------------------------------- /ch12/ex12_19.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_19.cpp 3 | // Exercise 12.19 4 | // 5 | // Created by pezy on 12/26/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Define your own version of StrBlobPtr and 9 | // update your StrBlob class with the appropriate friend declaration and begin 10 | // and end members. 11 | // 12 | // @See ex12_19.h 13 | 14 | #include "ex12_19.h" 15 | 16 | StrBlobPtr StrBlob::begin() 17 | { 18 | return StrBlobPtr(*this); 19 | } 20 | StrBlobPtr StrBlob::end() 21 | { 22 | return StrBlobPtr(*this, data->size()); 23 | } 24 | -------------------------------------------------------------------------------- /ch12/ex12_20.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_20.cpp 3 | // Exercise 12.20 4 | // 5 | // Created by pezy on 12/26/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write a program that reads an input file a line at a time into 9 | // a StrBlob and uses a StrBlobPtr to print each element in that StrBlob. 10 | 11 | #include "ex12_19.h" 12 | #include 13 | #include 14 | 15 | int main() 16 | { 17 | std::ifstream ifs("../data/book.txt"); 18 | StrBlob blob; 19 | for (std::string str; std::getline(ifs, str);) blob.push_back(str); 20 | for (StrBlobPtr pbeg(blob.begin()), pend(blob.end()); pbeg != pend; 21 | pbeg.incr()) 22 | std::cout << pbeg.deref() << std::endl; 23 | } -------------------------------------------------------------------------------- /ch12/ex12_22.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_22.cpp 3 | // CP5 4 | // 5 | // Created by pezy on 1/2/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | 9 | #include "ex12_22.h" 10 | 11 | ConstStrBlobPtr StrBlob::begin() const // should add const 12 | { 13 | return ConstStrBlobPtr(*this); 14 | } 15 | ConstStrBlobPtr StrBlob::end() const // should add const 16 | { 17 | return ConstStrBlobPtr(*this, data->size()); 18 | } -------------------------------------------------------------------------------- /ch12/ex12_23.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_23.cpp 3 | // Exercise 12.23 4 | // 5 | // Created by pezy on 12/30/14. 6 | // Updated by sanerror on 11/9/16. 7 | // Copyright (c) 2014 pezy. All rights reserved. 8 | // 9 | // Write a program to concatenate two string literals, putting the result in a 10 | // dynamically allocated array of char. 11 | // Write a program to concatenate two library strings that have the same value 12 | // as the literals used in the first program. 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | int main() { 19 | const char *c1 = "Hello "; 20 | const char *c2 = "World"; 21 | unsigned len = strlen(c1) + strlen(c2) + 1; 22 | char *r = new char[len](); 23 | strcat_s(r, len, c1); 24 | strcat_s(r, len, c2); 25 | std::cout << r << std::endl; 26 | 27 | std::string s1 = "Hello "; 28 | std::string s2 = "World"; 29 | strcpy_s(r, len, (s1 + s2).c_str()); 30 | std::cout << r << std::endl; 31 | 32 | delete[] r; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /ch12/ex12_24.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_24.cpp 3 | // Exercise 12.24 4 | // 5 | // Created by pezy on 12/30/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write a program that reads a string from the standard input into a 9 | // dynamically allocated character array. 10 | // Describe how your program handles varying size inputs. 11 | // Test your program by giving it a string of data that is longer than the 12 | // array size you've allocated. 13 | 14 | #include 15 | 16 | int main() 17 | { 18 | // need to tell the size. 19 | std::cout << "How long do you want the string? "; 20 | int size{0}; 21 | std::cin >> size; 22 | char* input = new char[size + 1](); 23 | std::cin.ignore(); 24 | std::cout << "input the string: "; 25 | std::cin.get(input, size + 1); 26 | std::cout << input; 27 | delete[] input; 28 | // Test: if longer than the array size, we will lost the characters which 29 | // are out of range. 30 | } 31 | -------------------------------------------------------------------------------- /ch12/ex12_26.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_26.cpp 3 | // Exercise 12.26 4 | // 5 | // Created by pezy on 12/30/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Rewrite the program on page 481 using an allocator. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | void input_reverse_output_string(int n) 15 | { 16 | std::allocator alloc; 17 | auto const p = alloc.allocate(n); 18 | std::string s; 19 | auto q = p; 20 | while (std::cin >> s && q != p + n) alloc.construct(q++, s); 21 | 22 | while (q != p) { 23 | std::cout << *--q << " "; 24 | alloc.destroy(q); 25 | } 26 | alloc.deallocate(p, n); 27 | } 28 | 29 | int main() 30 | { 31 | input_reverse_output_string(5); 32 | } 33 | -------------------------------------------------------------------------------- /ch12/ex12_27_30_TEST.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex12_27_TEST.cpp 3 | // Exercise 12.27 4 | // 5 | // Created by pezy on 12/31/14. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // The TextQuery and QueryResult classes use only capabilities that we have 9 | // already covered. 10 | // Without looking ahead, write your own versions of these classes. 11 | 12 | #include "ex12_27_30.h" 13 | #include 14 | 15 | void runQueries(std::ifstream& infile) 16 | { 17 | TextQuery tq(infile); 18 | while (true) { 19 | std::cout << "enter word to look for, or q to quit: "; 20 | string s; 21 | if (!(std::cin >> s) || s == "q") break; 22 | print(std::cout, tq.query(s)) << std::endl; 23 | } 24 | } 25 | 26 | int main() 27 | { 28 | std::ifstream file("../data/storyDataFile.txt"); 29 | runQueries(file); 30 | } 31 | -------------------------------------------------------------------------------- /ch13/ex13_05.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_05.h 3 | // CP5 4 | // 5 | // Created by pezy on 1/5/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Given the following sketch of a class, write a copy constructor that copies 9 | // all the members. 10 | // Your constructor should dynamically allocate a new string and copy the 11 | // object to which ps points, 12 | // rather than copying ps itself. 13 | 14 | #ifndef CP5_ex13_05_h 15 | #define CP5_ex13_05_h 16 | 17 | #include 18 | 19 | class HasPtr { 20 | public: 21 | HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0) 22 | { 23 | } 24 | HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 25 | private: 26 | std::string* ps; 27 | int i; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ch13/ex13_08.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_08.h 3 | // CP5 4 | // 5 | // Created by pezy on 1/12/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write the assignment operator for the HasPtr class from exercise 13.5 in 9 | // 13.1.1 (p. 499). 10 | // As with the copy constructor, your assignment operator should copy the 11 | // object to which ps points. 12 | // 13 | // See ex13_05.h 14 | 15 | #ifndef CP5_ex13_08_h 16 | #define CP5_ex13_08_h 17 | 18 | #include 19 | 20 | class HasPtr { 21 | public: 22 | HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0) 23 | { 24 | } 25 | HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 26 | HasPtr& operator=(const HasPtr& hp) 27 | { 28 | std::string* new_ps = new std::string(*hp.ps); 29 | delete ps; 30 | ps = new_ps; 31 | i = hp.i; 32 | return *this; 33 | } 34 | 35 | private: 36 | std::string* ps; 37 | int i; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ch13/ex13_11.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_11.h 3 | // CP5 4 | // 5 | // Created by pezy on 1/13/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Add a destructor to your HasPtr class from the previous exercises. 9 | // 10 | // See ex13_08.h 11 | 12 | #ifndef CP5_ex13_11_h 13 | #define CP5_ex13_11_h 14 | 15 | #include 16 | 17 | class HasPtr { 18 | public: 19 | HasPtr(const std::string& s = std::string()) : ps(new std::string(s)), i(0) 20 | { 21 | } 22 | HasPtr(const HasPtr& hp) : ps(new std::string(*hp.ps)), i(hp.i) {} 23 | HasPtr& operator=(const HasPtr& hp) 24 | { 25 | std::string* new_ps = new std::string(*hp.ps); 26 | delete ps; 27 | ps = new_ps; 28 | i = hp.i; 29 | return *this; 30 | } 31 | ~HasPtr() { delete ps; } 32 | private: 33 | std::string* ps; 34 | int i; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch13/ex13_17_1.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_17.cpp 3 | // Exercise 13.17 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write versions of numbered and f corresponding to the previous three 9 | // exercises 10 | // and check whether you correctly predicted the output. 11 | // 12 | // For 13.14 13 | 14 | #include 15 | 16 | class numbered { 17 | public: 18 | numbered() 19 | { 20 | static int unique = 10; 21 | mysn = unique++; 22 | } 23 | 24 | int mysn; 25 | }; 26 | 27 | void f(numbered s) 28 | { 29 | std::cout << s.mysn << std::endl; 30 | } 31 | 32 | int main() 33 | { 34 | numbered a, b = a, c = b; 35 | f(a); 36 | f(b); 37 | f(c); 38 | } 39 | 40 | // output 41 | // 10 42 | // 10 43 | // 10 44 | -------------------------------------------------------------------------------- /ch13/ex13_17_2.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_17.cpp 3 | // Exercise 13.17 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write versions of numbered and f corresponding to the previous three 9 | // exercises 10 | // and check whether you correctly predicted the output. 11 | // 12 | // For 13.15 13 | 14 | #include 15 | 16 | class numbered { 17 | public: 18 | numbered() 19 | { 20 | static int unique = 10; 21 | mysn = unique++; 22 | } 23 | 24 | numbered(const numbered& n) { mysn = n.mysn + 1; } 25 | 26 | int mysn; 27 | }; 28 | 29 | void f(numbered s) 30 | { 31 | std::cout << s.mysn << std::endl; 32 | } 33 | 34 | int main() 35 | { 36 | numbered a, b = a, c = b; 37 | f(a); 38 | f(b); 39 | f(c); 40 | } 41 | 42 | // output 43 | // 11 44 | // 12 45 | // 13 46 | -------------------------------------------------------------------------------- /ch13/ex13_17_3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_17.cpp 3 | // Exercise 13.17 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Write versions of numbered and f corresponding to the previous three 9 | // exercises 10 | // and check whether you correctly predicted the output. 11 | // 12 | // For 13.16 13 | 14 | #include 15 | 16 | class numbered { 17 | public: 18 | numbered() 19 | { 20 | static int unique = 10; 21 | mysn = unique++; 22 | } 23 | 24 | numbered(const numbered& n) { mysn = n.mysn + 1; } 25 | 26 | int mysn; 27 | }; 28 | 29 | void f(const numbered& s) 30 | { 31 | std::cout << s.mysn << std::endl; 32 | } 33 | 34 | int main() 35 | { 36 | numbered a, b = a, c = b; 37 | f(a); 38 | f(b); 39 | f(c); 40 | } 41 | 42 | // output 43 | // 10 44 | // 11 45 | // 12 46 | -------------------------------------------------------------------------------- /ch13/ex13_18.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_18.cpp 3 | // Exercise 13.18 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Define an Employee class that contains an employee name and a unique 9 | // employee identifier. 10 | // Give the class a default constructor and a constructor that 11 | // takes a string representing the employee’s name. 12 | // Each constructor should generate a unique ID by incrementing a static data 13 | // member. 14 | // 15 | 16 | #include "ex13_18.h" 17 | 18 | int Employee::s_increment = 0; 19 | 20 | Employee::Employee() 21 | { 22 | id_ = s_increment++; 23 | } 24 | 25 | Employee::Employee(const string& name) 26 | { 27 | id_ = s_increment++; 28 | name_ = name; 29 | } -------------------------------------------------------------------------------- /ch13/ex13_18.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_18.h 3 | // Exercise 13.18 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Define an Employee class that contains an employee name and a unique 9 | // employee identifier. 10 | // Give the class a default constructor and a constructor that 11 | // takes a string representing the employee’s name. 12 | // Each constructor should generate a unique ID by incrementing a static data 13 | // member. 14 | // 15 | 16 | #ifndef CP5_ex13_18_h 17 | #define CP5_ex13_18_h 18 | 19 | #include 20 | using std::string; 21 | 22 | class Employee { 23 | public: 24 | Employee(); 25 | Employee(const string& name); 26 | 27 | const int id() const { return id_; } 28 | 29 | private: 30 | string name_; 31 | int id_; 32 | static int s_increment; 33 | }; 34 | 35 | #endif -------------------------------------------------------------------------------- /ch13/ex13_19.h: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_19.h 3 | // Exercise 13.19 4 | // 5 | // Created by pezy on 1/15/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Does your Employee class need to define its own versions of the copy-control 9 | // members? 10 | // If so, why? If not, why not? 11 | // Implement whatever copy-control members you think Employee needs. 12 | // 13 | // Answer: No, cause there really is no sensible meaning. employee can't copy 14 | // in real world. 15 | 16 | #ifndef CP5_ex13_19_h 17 | #define CP5_ex13_19_h 18 | 19 | #include 20 | using std::string; 21 | 22 | class Employee { 23 | public: 24 | Employee(); 25 | Employee(const string& name); 26 | Employee(const Employee&) = delete; 27 | Employee& operator=(const Employee&) = delete; 28 | 29 | const int id() const { return id_; } 30 | 31 | private: 32 | string name_; 33 | int id_; 34 | static int s_increment; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch13/ex13_22.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yogykwan/cpp-primer-workbook/fe1277a4be14ea6517e8d6a255ab25b5125fe2b7/ch13/ex13_22.h -------------------------------------------------------------------------------- /ch13/ex13_26.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_26.cpp 3 | // Exercise 13.26 4 | // 5 | // Created by pezy on 1/19/15. 6 | // Copyright (c) 2014 pezy. All rights reserved. 7 | // 8 | // Write your own version of the StrBlob class described in the previous 9 | // exercise. 10 | // 11 | // @See ex12_22 and ex13_25 12 | 13 | #include "ex13_26.h" 14 | 15 | ConstStrBlobPtr StrBlob::begin() const // should add const 16 | { 17 | return ConstStrBlobPtr(*this); 18 | } 19 | ConstStrBlobPtr StrBlob::end() const // should add const 20 | { 21 | return ConstStrBlobPtr(*this, data->size()); 22 | } 23 | 24 | StrBlob& StrBlob::operator=(const StrBlob& sb) 25 | { 26 | data = std::make_shared>(*sb.data); 27 | return *this; 28 | } 29 | -------------------------------------------------------------------------------- /ch13/ex13_28.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ex13_28.cpp 3 | // Exercise 13.28 4 | // 5 | // Created by pezy on 1/20/15. 6 | // Copyright (c) 2015 pezy. All rights reserved. 7 | // 8 | // Given the following classes, implement a default constructor and the 9 | // necessary copy-control members. 10 | 11 | #include "ex13_28.h" 12 | 13 | TreeNode& TreeNode::operator=(const TreeNode& rhs) 14 | { 15 | ++*rhs.count; 16 | if (--*count == 0) { 17 | if (left) { 18 | delete left; 19 | left = nullptr; 20 | } 21 | if (right) { 22 | delete right; 23 | right = nullptr; 24 | } 25 | 26 | delete count; 27 | count = nullptr; 28 | } 29 | value = rhs.value; 30 | left = rhs.left; 31 | right = rhs.right; 32 | count = rhs.count; 33 | return *this; 34 | } 35 | 36 | BinStrTree& BinStrTree::operator=(const BinStrTree& bst) 37 | { 38 | TreeNode* new_root = new TreeNode(*bst.root); 39 | delete root; 40 | root = new_root; 41 | return *this; 42 | } 43 | -------------------------------------------------------------------------------- /ch13/ex13_34_36_37_TEST.cpp: -------------------------------------------------------------------------------- 1 | // Unit Test for exercise 13_34_36_37. 2 | 3 | #include "ex13_34_36_37.h" 4 | 5 | int main() 6 | { 7 | Message firstMail("hello"); 8 | Message signInMail("welcome to cppprimer"); 9 | Folder mailBox; 10 | 11 | firstMail.print_debug(); // print: "hello" 12 | firstMail.save(mailBox); // send to mailBox 13 | mailBox.print_debug(); // print: "hello" 14 | 15 | signInMail.print_debug(); // print "welcome to cppprimer" 16 | signInMail.save(mailBox); // send to mailBox 17 | mailBox.print_debug(); // print "welcome to cppprimer hello" 18 | 19 | firstMail = firstMail; // test for assignment to self. 20 | firstMail.print_debug(); // print "hello" 21 | mailBox.print_debug(); // print "welcome to cppprimer hello" 22 | } 23 | -------------------------------------------------------------------------------- /ch13/ex13_42.cpp: -------------------------------------------------------------------------------- 1 | #include "ex13_42_TextQuery.h" 2 | #include 3 | 4 | void runQueries(std::ifstream& infile) 5 | { 6 | TextQuery tq(infile); 7 | while (true) { 8 | std::cout << "enter word to look for, or q to quit: "; 9 | std::string s; 10 | if (!(std::cin >> s) || s == "q") break; 11 | print(std::cout, tq.query(s)) << std::endl; 12 | } 13 | } 14 | 15 | int main() 16 | { 17 | std::ifstream file("../data/storyDataFile.txt"); 18 | runQueries(file); 19 | } 20 | -------------------------------------------------------------------------------- /ch13/ex13_44_47.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_STRING_H__ 2 | #define CP5_STRING_H__ 3 | 4 | #include 5 | 6 | class String { 7 | public: 8 | String() : String("") {} 9 | String(const char*); 10 | String(const String&); 11 | String& operator=(const String&); 12 | ~String(); 13 | 14 | const char* c_str() const { return elements; } 15 | size_t size() const { return end - elements; } 16 | size_t length() const { return end - elements - 1; } 17 | 18 | private: 19 | std::pair alloc_n_copy(const char*, const char*); 20 | void range_initializer(const char*, const char*); 21 | void free(); 22 | 23 | private: 24 | char* elements; 25 | char* end; 26 | std::allocator alloc; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /ch13/ex13_49_Message_TEST.cpp: -------------------------------------------------------------------------------- 1 | // Unit Test for exercise 13_49_Message. 2 | 3 | #include "ex13_49_Message.h" 4 | 5 | int main() 6 | { 7 | Message firstMail("hello"); 8 | Message signInMail("welcome to cppprimer"); 9 | Folder mailBox; 10 | 11 | firstMail.save(mailBox); 12 | signInMail.save(mailBox); 13 | mailBox.print_debug(); 14 | 15 | firstMail = std::move(signInMail); 16 | mailBox.print_debug(); 17 | } 18 | -------------------------------------------------------------------------------- /ch13/ex13_49_String.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_STRING_H__ 2 | #define CP5_STRING_H__ 3 | 4 | #include 5 | 6 | #ifndef _MSC_VER 7 | #define NOEXCEPT noexcept 8 | #else 9 | #define NOEXCEPT 10 | #endif 11 | 12 | class String { 13 | public: 14 | String() : String("") {} 15 | String(const char*); 16 | String(const String&); 17 | String& operator=(const String&); 18 | String(String&&) NOEXCEPT; 19 | String& operator=(String&&) NOEXCEPT; 20 | ~String(); 21 | 22 | const char* c_str() const { return elements; } 23 | size_t size() const { return end - elements; } 24 | size_t length() const { return end - elements - 1; } 25 | 26 | private: 27 | std::pair alloc_n_copy(const char*, const char*); 28 | void range_initializer(const char*, const char*); 29 | void free(); 30 | 31 | private: 32 | char* elements; 33 | char* end; 34 | std::allocator alloc; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ch13/ex13_53.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_ex13_53_h 2 | #define CP5_ex13_53_h 3 | 4 | #include 5 | 6 | class HasPtr { 7 | public: 8 | friend void swap(HasPtr&, HasPtr&); 9 | HasPtr(const std::string& s = std::string()); 10 | HasPtr(const HasPtr& hp); 11 | HasPtr(HasPtr&& p) noexcept; 12 | HasPtr& operator=(HasPtr rhs); 13 | // HasPtr& operator=(const HasPtr &rhs); 14 | // HasPtr& operator=(HasPtr &&rhs) noexcept; 15 | ~HasPtr(); 16 | 17 | private: 18 | std::string* ps; 19 | int i; 20 | }; 21 | 22 | #endif // CP5_ex13_53_h 23 | -------------------------------------------------------------------------------- /ch13/ex13_53_test.cpp: -------------------------------------------------------------------------------- 1 | #include "ex13_53.h" 2 | 3 | int main() 4 | { 5 | HasPtr hp1("hello"), hp2("World"), *pH = new HasPtr("World"); 6 | hp1 = hp2; 7 | hp1 = std::move(*pH); 8 | } 9 | 10 | // when used copy-and-swap 11 | 12 | // call constructor 13 | // call constructor 14 | // call constructor 15 | // call copy constructor !!! 16 | // call swap !!! 17 | // call destructor !!! 18 | // call move constructor !!! 19 | // call swap !!! 20 | // call destructor !!! 21 | // call destructor 22 | // call destructor 23 | 24 | // when used two assignment operator. 25 | 26 | // call constructor 27 | // call constructor 28 | // call constructor 29 | // call copy assignment !!! 30 | // call move assignment !!! 31 | // call destructor 32 | // call destructor 33 | -------------------------------------------------------------------------------- /ch13/ex13_58.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::vector; 6 | using std::sort; 7 | 8 | class Foo { 9 | public: 10 | Foo sorted()&&; 11 | Foo sorted() const&; 12 | 13 | private: 14 | vector data; 15 | }; 16 | 17 | Foo Foo::sorted() && 18 | { 19 | sort(data.begin(), data.end()); 20 | std::cout << "&&" << std::endl; // debug 21 | return *this; 22 | } 23 | 24 | Foo Foo::sorted() const & 25 | { 26 | // Foo ret(*this); 27 | // sort(ret.data.begin(), ret.data.end()); 28 | // return ret; 29 | 30 | std::cout << "const &" << std::endl; // debug 31 | 32 | // Foo ret(*this); 33 | // ret.sorted(); // Exercise 13.56 34 | // return ret; 35 | 36 | return Foo(*this).sorted(); // Exercise 13.57 37 | } 38 | 39 | int main() 40 | { 41 | Foo().sorted(); // call "&&" 42 | Foo f; 43 | f.sorted(); // call "const &" 44 | } 45 | -------------------------------------------------------------------------------- /ch14/ex14_02_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_02.h" 2 | 3 | int main() 4 | { 5 | Sales_data cp5; 6 | std::cin >> cp5; 7 | std::cout << cp5 << std::endl; 8 | } 9 | -------------------------------------------------------------------------------- /ch14/ex14_05.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_05.h" 2 | 3 | std::istream& operator>>(std::istream& in, Book& book) 4 | { 5 | in >> book.no_ >> book.name_ >> book.author_ >> book.pubdate_; 6 | if (!in) book = Book(); 7 | return in; 8 | } 9 | 10 | std::ostream& operator<<(std::ostream& out, const Book& book) 11 | { 12 | out << book.no_ << " " << book.name_ << " " << book.author_ << " " 13 | << book.pubdate_; 14 | return out; 15 | } 16 | 17 | bool operator==(const Book& lhs, const Book& rhs) 18 | { 19 | return lhs.no_ == rhs.no_; 20 | } 21 | 22 | bool operator!=(const Book& lhs, const Book& rhs) 23 | { 24 | return !(lhs == rhs); 25 | } 26 | -------------------------------------------------------------------------------- /ch14/ex14_05.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOK_H 2 | #define BOOK_H 3 | 4 | #include 5 | #include 6 | 7 | class Book { 8 | friend std::istream& operator>>(std::istream&, Book&); 9 | friend std::ostream& operator<<(std::ostream&, const Book&); 10 | friend bool operator==(const Book&, const Book&); 11 | friend bool operator!=(const Book&, const Book&); 12 | 13 | public: 14 | Book() = default; 15 | Book(unsigned no, std::string name, std::string author, std::string pubdate) 16 | : no_(no), name_(name), author_(author), pubdate_(pubdate) 17 | { 18 | } 19 | Book(std::istream& in) { in >> *this; } 20 | 21 | private: 22 | unsigned no_; 23 | std::string name_; 24 | std::string author_; 25 | std::string pubdate_; 26 | }; 27 | 28 | std::istream& operator>>(std::istream&, Book&); 29 | std::ostream& operator<<(std::ostream&, const Book&); 30 | bool operator==(const Book&, const Book&); 31 | bool operator!=(const Book&, const Book&); 32 | 33 | #endif // BOOK_H 34 | -------------------------------------------------------------------------------- /ch14/ex14_05_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_05.h" 2 | 3 | int main() 4 | { 5 | Book book1(123, "CP5", "Lippman", "2012"); 6 | Book book2(123, "CP5", "Lippman", "2012"); 7 | 8 | if (book1 == book2) std::cout << book1 << std::endl; 9 | } 10 | -------------------------------------------------------------------------------- /ch14/ex14_07.h: -------------------------------------------------------------------------------- 1 | #ifndef CP5_STRING_H__ 2 | #define CP5_STRING_H__ 3 | 4 | #include 5 | #include 6 | 7 | class String { 8 | friend std::ostream& operator<<(std::ostream&, const String&); 9 | 10 | public: 11 | String() : String("") {} 12 | String(const char*); 13 | String(const String&); 14 | String& operator=(const String&); 15 | ~String(); 16 | 17 | const char* c_str() const { return elements; } 18 | size_t size() const { return end - elements; } 19 | size_t length() const { return end - elements - 1; } 20 | 21 | private: 22 | std::pair alloc_n_copy(const char*, const char*); 23 | void range_initializer(const char*, const char*); 24 | void free(); 25 | 26 | private: 27 | char* elements; 28 | char* end; 29 | std::allocator alloc; 30 | }; 31 | 32 | std::ostream& operator<<(std::ostream&, const String&); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /ch14/ex14_07_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_07.h" 2 | 3 | int main() 4 | { 5 | String str("Hello World"); 6 | std::cout << str << std::endl; 7 | } 8 | -------------------------------------------------------------------------------- /ch14/ex14_15_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_15.h" 2 | 3 | int main() 4 | { 5 | Book cp5_1(12345, "CP5", "Lippmen", "2012", 2); 6 | Book cp5_2(12345, "CP5", "Lippmen", "2012", 4); 7 | 8 | std::cout << cp5_1 + cp5_2 << std::endl; 9 | } 10 | -------------------------------------------------------------------------------- /ch14/ex14_16_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_16_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb{"Hello", "World", "Pezy"}; 7 | 8 | for (ConstStrBlobPtr iter = sb.cbegin(); iter != sb.cend(); iter.incr()) { 9 | std::cout << iter.deref() << " "; 10 | } 11 | std::cout << std::endl; 12 | } 13 | -------------------------------------------------------------------------------- /ch14/ex14_18_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_18_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2{"a", "b", "b"}; 8 | 9 | if (sb1 > sb2) { 10 | for (ConstStrBlobPtr iter = sb1.cbegin(); iter < sb1.cend(); 11 | iter.incr()) 12 | std::cout << iter.deref() << " "; 13 | std::cout << std::endl; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ch14/ex14_22_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_22.h" 2 | 3 | int main() 4 | { 5 | std::string strCp5("C++ Primer 5th"); 6 | Sales_data cp5 = strCp5; 7 | std::cout << cp5 << std::endl; 8 | } 9 | -------------------------------------------------------------------------------- /ch14/ex14_26_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_26_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2 = sb1; 8 | 9 | sb2[2] = "b"; 10 | 11 | if (sb1 > sb2) { 12 | for (ConstStrBlobPtr iter = sb1.cbegin(); iter < sb1.cend(); 13 | iter.incr()) 14 | std::cout << iter.deref() << " "; 15 | std::cout << std::endl; 16 | } 17 | 18 | StrBlobPtr iter(sb2); 19 | std::cout << iter[2] << std::endl; 20 | } 21 | -------------------------------------------------------------------------------- /ch14/ex14_27_28_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_27_28_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2 = sb1; 8 | 9 | sb2[2] = "b"; 10 | 11 | if (sb1 > sb2) { 12 | for (StrBlobPtr iter = sb1.begin(); iter < sb1.end(); ++iter) 13 | std::cout << iter.deref() << " "; 14 | std::cout << std::endl; 15 | } 16 | 17 | ConstStrBlobPtr iter(sb2); 18 | std::cout << (iter + 2).deref() << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch14/ex14_30_StrBlobTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_30_StrBlob.h" 2 | #include 3 | 4 | int main() 5 | { 6 | StrBlob sb1{"a", "b", "c"}; 7 | StrBlob sb2 = sb1; 8 | 9 | sb2[2] = "b"; 10 | 11 | if (sb1 > sb2) { 12 | for (ConstStrBlobPtr iter = sb1.cbegin(); iter != sb1.cend(); ++iter) 13 | std::cout << *iter << " "; 14 | std::cout << std::endl; 15 | } 16 | 17 | ConstStrBlobPtr iter(sb2); 18 | std::cout << iter->size() << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch14/ex14_32.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_32.h" 2 | #include "ex14_30_StrBlob.h" 3 | #include 4 | 5 | StrBlobPtr& StrBlobPtr_pointer::operator*() 6 | { 7 | return *(this->pointer); 8 | } 9 | 10 | StrBlobPtr* StrBlobPtr_pointer::operator->() 11 | { 12 | return &this->operator*(); 13 | } 14 | 15 | int main() 16 | { 17 | StrBlob sb{"hello", "world"}; 18 | StrBlobPtr iter = sb.begin(); 19 | StrBlobPtr_pointer p(&iter); 20 | std::cout << p->deref() << std::endl; 21 | } 22 | -------------------------------------------------------------------------------- /ch14/ex14_32.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file StrBlobPtr_pointer.h 3 | * @author Alan.W 4 | * @date 19 JAN 2014 5 | * @remark a class that holds a pointer to a StrBlobPtr. 6 | ***************************************************************************/ 7 | 8 | #ifndef STRBLOBPTR_POINTER_H 9 | #define STRBLOBPTR_POINTER_H 10 | 11 | class StrBlobPtr; 12 | 13 | /** 14 | * @brief a class that holds a pointer to a StrBlobPtr. 15 | */ 16 | class StrBlobPtr_pointer { 17 | public: 18 | StrBlobPtr_pointer() = default; 19 | StrBlobPtr_pointer(StrBlobPtr* p) : pointer(p) {} 20 | 21 | StrBlobPtr& operator*(); 22 | StrBlobPtr* operator->(); 23 | 24 | private: 25 | StrBlobPtr* pointer = nullptr; 26 | }; 27 | 28 | #endif // STRBLOBPTR_POINTER_H 29 | -------------------------------------------------------------------------------- /ch14/ex14_35.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class GetInput { 5 | public: 6 | GetInput(std::istream& i = std::cin) : is(i) {} 7 | std::string operator()() const 8 | { 9 | std::string str; 10 | std::getline(is, str); 11 | return is ? str : std::string(); 12 | } 13 | 14 | private: 15 | std::istream& is; 16 | }; 17 | 18 | int main() 19 | { 20 | GetInput getInput; 21 | std::cout << getInput() << std::endl; 22 | } 23 | -------------------------------------------------------------------------------- /ch14/ex14_36.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class GetInput { 6 | public: 7 | GetInput(std::istream& i = std::cin) : is(i) {} 8 | std::string operator()() const 9 | { 10 | std::string str; 11 | std::getline(is, str); 12 | return is ? str : std::string(); 13 | } 14 | 15 | private: 16 | std::istream& is; 17 | }; 18 | 19 | int main() 20 | { 21 | GetInput getInput; 22 | std::vector vec; 23 | for (std::string tmp; !(tmp = getInput()).empty();) vec.push_back(tmp); 24 | for (const auto& str : vec) std::cout << str << " "; 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /ch14/ex14_37.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class IsEqual { 6 | int value; 7 | 8 | public: 9 | IsEqual(int v) : value(v) {} 10 | bool operator()(int elem) { return elem == value; } 11 | }; 12 | 13 | int main() 14 | { 15 | std::vector vec = {3, 2, 1, 4, 3, 7, 8, 6}; 16 | std::replace_if(vec.begin(), vec.end(), IsEqual(3), 5); 17 | for (int i : vec) std::cout << i << " "; 18 | std::cout << std::endl; 19 | } 20 | -------------------------------------------------------------------------------- /ch14/ex14_42.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | using std::placeholders::_1; 10 | 11 | std::vector ivec{1, 111, 1111, 11111}; 12 | int count = std::count_if(ivec.cbegin(), ivec.cend(), 13 | std::bind(std::greater(), _1, 1024)); 14 | std::cout << count << std::endl; 15 | 16 | std::vector svec{"pooh", "pooh", "pezy", "pooh"}; 17 | auto found = 18 | std::find_if(svec.cbegin(), svec.cend(), 19 | std::bind(std::not_equal_to(), _1, "pooh")); 20 | std::cout << *found << std::endl; 21 | 22 | std::transform(ivec.begin(), ivec.end(), ivec.begin(), 23 | std::bind(std::multiplies(), _1, 2)); 24 | for (int i : ivec) std::cout << i << " "; 25 | std::cout << std::endl; 26 | } 27 | -------------------------------------------------------------------------------- /ch14/ex14_43.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author XDXX, Yue Wang 4 | * @date 5/24/2015 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 14.43: 10 | //! Using library function objects, determine whether a given int value is 11 | //! divisible by any element in a container of ints. 12 | //! 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int main() 20 | { 21 | auto data = {2, 3, 4, 5}; 22 | int input; 23 | std::cin >> input; 24 | std::modulus mod; 25 | auto predicator = [&](int i) { return 0 == mod(input, i); }; 26 | auto is_divisible = std::any_of(data.begin(), data.end(), predicator); 27 | std::cout << (is_divisible ? "Yes!" : "No!") << std::endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch14/ex14_45_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_45.h" 2 | 3 | int main() 4 | { 5 | Sales_data cp5("C++ Primer 5th", 4, 106.5); 6 | std::cout << cp5 << std::endl; 7 | std::cout << static_cast(cp5) << std::endl; 8 | std::cout << static_cast(cp5) << std::endl; 9 | } 10 | -------------------------------------------------------------------------------- /ch14/ex14_49_TEST.cpp: -------------------------------------------------------------------------------- 1 | #include "ex14_49.h" 2 | 3 | int main() 4 | { 5 | Date date(12, 4, 2015); 6 | if (static_cast(date)) std::cout << date << std::endl; 7 | } 8 | -------------------------------------------------------------------------------- /ch15/ex15.1.2.3/CppPrimer.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | CONFIG += console 3 | CONFIG -= app_bundle 4 | CONFIG -= qt 5 | CONFIG += c++11 6 | 7 | 8 | SOURCES += main.cpp \ 9 | quote.cpp 10 | 11 | HEADERS += \ 12 | quote.h 13 | 14 | -------------------------------------------------------------------------------- /ch15/ex15.1.2.3/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.1.2.3/quote.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | 6 | class Quote 7 | { 8 | public: 9 | Quote() = default; 10 | Quote(const std::string &b, double p) : 11 | bookNo(b), price(p) { } 12 | 13 | std::string isbn() const { return bookNo; } 14 | virtual double net_price(std::size_t n) const { return n * price; } 15 | 16 | virtual ~Quote() = default; 17 | 18 | private: 19 | std::string bookNo; 20 | 21 | protected: 22 | double price = 0.0; 23 | 24 | }; 25 | 26 | #endif // QUOTE_H 27 | -------------------------------------------------------------------------------- /ch15/ex15.11/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= min_qty ? 1 - discount : 1); 6 | } 7 | 8 | void Bulk_quote::debug() const 9 | { 10 | Quote::debug(); 11 | std::cout << "min_qty= " << this->min_qty << " " 12 | << "discount= " << this->discount<< " "; 13 | } 14 | -------------------------------------------------------------------------------- /ch15/ex15.11/bulk_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include"quote.h" 4 | 5 | class Bulk_quote : public Quote 6 | { 7 | public: 8 | Bulk_quote() = default; 9 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 10 | Quote(b,p), min_qty(q), discount(disc) { } 11 | 12 | double net_price(std::size_t n) const override; 13 | void debug() const override; 14 | 15 | private: 16 | std::size_t min_qty = 0; 17 | double discount = 0.0; 18 | }; 19 | 20 | #endif // BULK_QUOTE_H 21 | -------------------------------------------------------------------------------- /ch15/ex15.11/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | void Limit_quote::debug() const 5 | { 6 | Quote::debug(); 7 | std::cout << "max_qty= " << this->max_qty << " " 8 | << "discount= " << this->discount<< " "; 9 | } 10 | -------------------------------------------------------------------------------- /ch15/ex15.11/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "quote.h" 5 | 6 | class Limit_quote : public Quote 7 | { 8 | public: 9 | Limit_quote(); 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Quote(b,p), max_qty(max), discount(disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price * (n < max_qty ? 1 - discount : 1 ); } 15 | 16 | void debug() const override; 17 | 18 | private: 19 | std::size_t max_qty = 0; 20 | double discount = 0.0; 21 | }; 22 | 23 | #endif // LIMIT_QUOTE_H 24 | -------------------------------------------------------------------------------- /ch15/ex15.11/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | void Quote::debug() const 4 | { 5 | std::cout << "data members of this class:\n" 6 | << "bookNo= " <bookNo << " " 7 | << "price= " <price<< " "; 8 | } 9 | -------------------------------------------------------------------------------- /ch15/ex15.11/quote.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | #include 6 | 7 | class Quote 8 | { 9 | public: 10 | Quote() = default; 11 | Quote(const std::string &b, double p) : 12 | bookNo(b), price(p) { } 13 | 14 | std::string isbn() const { return bookNo; } 15 | virtual double net_price(std::size_t n) const { return n * price; } 16 | virtual void debug() const; 17 | 18 | virtual ~Quote() = default; 19 | 20 | private: 21 | std::string bookNo; 22 | 23 | protected: 24 | double price = 0.0; 25 | 26 | }; 27 | 28 | #endif // QUOTE_H 29 | -------------------------------------------------------------------------------- /ch15/ex15.12.13.14/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= min_qty ? 1 - discount : 1); 6 | } 7 | 8 | void Bulk_quote::debug() const 9 | { 10 | std::cout << "data members of this class:\n" 11 | << "min_qty= " << this->min_qty << " " 12 | << "discount= " << this->discount<< " \n"; 13 | } 14 | -------------------------------------------------------------------------------- /ch15/ex15.12.13.14/bulk_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include 4 | 5 | class Bulk_quote : public Quote 6 | { 7 | public: 8 | Bulk_quote() = default; 9 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 10 | Quote(b,p), min_qty(q), discount(disc) { } 11 | 12 | double net_price(std::size_t n) const override; 13 | void debug() const override; 14 | 15 | private: 16 | std::size_t min_qty = 0; 17 | double discount = 0.0; 18 | }; 19 | 20 | #endif // BULK_QUOTE_H 21 | -------------------------------------------------------------------------------- /ch15/ex15.12.13.14/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | void Limit_quote::debug() const 5 | { 6 | std::cout << "data members of this class:\n" 7 | << "max_qty= " << this->max_qty << " " 8 | << "discount= " << this->discount<< " \n"; 9 | } 10 | -------------------------------------------------------------------------------- /ch15/ex15.12.13.14/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "quote.h" 5 | 6 | class Limit_quote : public Quote 7 | { 8 | public: 9 | Limit_quote(); 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Quote(b,p), max_qty(max), discount(disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price * (n < max_qty ? 1 - discount : 1 ); } 15 | 16 | void debug() const override; 17 | 18 | private: 19 | std::size_t max_qty = 0; 20 | double discount = 0.0; 21 | }; 22 | 23 | #endif // LIMIT_QUOTE_H 24 | -------------------------------------------------------------------------------- /ch15/ex15.12.13.14/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | void Quote::debug() const 4 | { 5 | std::cout << "data members of this class:\n" 6 | << "bookNo= " <bookNo << " " 7 | << "price= " <price<< " \n"; 8 | } 9 | -------------------------------------------------------------------------------- /ch15/ex15.12.13.14/quote.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | #include 6 | 7 | class Quote 8 | { 9 | public: 10 | Quote() = default; 11 | Quote(const std::string &b, double p) : 12 | bookNo(b), price(p) { } 13 | 14 | std::string isbn() const { return bookNo; } 15 | virtual double net_price(std::size_t n) const { return n * price; } 16 | virtual void debug() const; 17 | 18 | virtual ~Quote() = default; 19 | 20 | private: 21 | std::string bookNo; 22 | 23 | protected: 24 | double price = 0.0; 25 | 26 | }; 27 | 28 | #endif // QUOTE_H 29 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= quantity ? 1 - discount : 1); 6 | } 7 | 8 | void Bulk_quote::debug() const 9 | { 10 | Quote::debug(); 11 | std::cout //<< "data members of this class:\n" 12 | << "min_qty= " << quantity << " " 13 | << "discount= " << discount<< " "; 14 | } 15 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/bulk_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include "disc_quote.h" 4 | 5 | class Bulk_quote : public Disc_quote 6 | { 7 | public: 8 | Bulk_quote() = default; 9 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 10 | Disc_quote(b,p,q,disc) { } 11 | 12 | double net_price(std::size_t n) const override; 13 | void debug() const override; 14 | 15 | 16 | }; 17 | 18 | #endif // BULK_QUOTE_H 19 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/disc_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "disc_quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/disc_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef DISC_QUOTE_H 2 | #define DISC_QUOTE_H 3 | 4 | #include "quote.h" 5 | class Disc_quote : public Quote 6 | { 7 | public: 8 | Disc_quote(); 9 | Disc_quote(const std::string& b, double p, std::size_t q, double d) : 10 | Quote(b, p), quantity(q), discount(d) { } 11 | 12 | virtual double net_price(std::size_t n) const override = 0; 13 | 14 | protected: 15 | std::size_t quantity; 16 | double discount; 17 | }; 18 | 19 | #endif // DISC_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | void Limit_quote::debug() const 5 | { 6 | Quote::debug(); 7 | std::cout //<< "data members of this class:\n" 8 | << "max_qty= " << quantity << " " 9 | << "discount= " << discount<< " "; 10 | } 11 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "disc_quote.h" 5 | 6 | class Limit_quote : public Disc_quote 7 | { 8 | public: 9 | Limit_quote() = default; 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Disc_quote(b,p,max,disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price * (n < quantity ? 1 - discount : 1 ); } 15 | 16 | void debug() const override; 17 | }; 18 | 19 | #endif // LIMIT_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | void Quote::debug() const 4 | { 5 | std::cout //<< "data members of this class:\n" 6 | << "bookNo= " <bookNo << " " 7 | << "price= " <price<< " "; 8 | } 9 | -------------------------------------------------------------------------------- /ch15/ex15.15.16.17/quote.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | #include 6 | 7 | class Quote 8 | { 9 | public: 10 | Quote() = default; 11 | Quote(const std::string &b, double p) : 12 | bookNo(b), price(p) { } 13 | 14 | std::string isbn() const { return bookNo; } 15 | virtual double net_price(std::size_t n) const { return n * price; } 16 | virtual void debug() const; 17 | 18 | virtual ~Quote() = default; 19 | 20 | private: 21 | std::string bookNo; 22 | 23 | protected: 24 | double price = 0.0; 25 | 26 | }; 27 | 28 | #endif // QUOTE_H 29 | -------------------------------------------------------------------------------- /ch15/ex15.26/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= quantity ? 1 - discount : 1); 6 | } 7 | 8 | void Bulk_quote::debug() const 9 | { 10 | std::cout //<< "data members of this class:\n" 11 | << "min_qty= " << quantity << " " 12 | << "discount= " << this->discount<< " \n"; 13 | } 14 | -------------------------------------------------------------------------------- /ch15/ex15.26/disc_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "disc_quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.26/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | void Limit_quote::debug() const 5 | { 6 | std::cout //<< "data members of this class:\n" 7 | << "max_qty= " << this->quantity << " " 8 | << "discount= " << this->discount<< " \n"; 9 | } 10 | -------------------------------------------------------------------------------- /ch15/ex15.26/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "disc_quote.h" 5 | 6 | class Limit_quote : public Disc_quote 7 | { 8 | public: 9 | Limit_quote() = default; 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Disc_quote(b,p,max,disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price * (n < quantity ? 1 - discount : 1 ); } 15 | 16 | void debug() const override; 17 | }; 18 | 19 | #endif // LIMIT_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.26/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | void Quote::debug() const 4 | { 5 | std::cout //<< "data members of this class:\n" 6 | << "bookNo= " <bookNo << " " 7 | << "price= " <price<< " \n"; 8 | } 9 | -------------------------------------------------------------------------------- /ch15/ex15.27/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= quantity ? 1 - discount : 1); 6 | } 7 | 8 | void Bulk_quote::debug() const 9 | { 10 | std::cout //<< "data members of this class:\n" 11 | << "min_qty= " << quantity << " " 12 | << "discount= " << this->discount<< " \n"; 13 | } 14 | -------------------------------------------------------------------------------- /ch15/ex15.27/disc_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "disc_quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.27/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | void Limit_quote::debug() const 5 | { 6 | std::cout //<< "data members of this class:\n" 7 | << "max_qty= " << this->quantity << " " 8 | << "discount= " << this->discount<< " \n"; 9 | } 10 | -------------------------------------------------------------------------------- /ch15/ex15.27/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "disc_quote.h" 5 | 6 | class Limit_quote : public Disc_quote 7 | { 8 | public: 9 | Limit_quote() = default; 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Disc_quote(b,p,max,disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price * (n < quantity ? 1 - discount : 1 ); } 15 | 16 | void debug() const override; 17 | }; 18 | 19 | #endif // LIMIT_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.27/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 28 Jan 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 15.27: 10 | //! Redefine your Bulk_quote class to inherit its constructors. 11 | // rules: 1. only inherit from the direct base class. 12 | // 2. default,copy and move constructors can not inherit. 13 | // 3. any data members of its own are default initialized. 14 | // 4. the rest details are in the section section 15.7.4. 15 | //! 16 | 17 | 18 | #include 19 | #include 20 | 21 | #include "quote.h" 22 | #include "bulk_quote.h" 23 | #include "limit_quote.h" 24 | #include "disc_quote.h" 25 | 26 | 27 | int main() 28 | { 29 | Bulk_quote bq("sss",20.0,2,0.3); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /ch15/ex15.27/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | void Quote::debug() const 4 | { 5 | std::cout //<< "data members of this class:\n" 6 | << "bookNo= " <bookNo << " " 7 | << "price= " <price<< " \n"; 8 | } 9 | -------------------------------------------------------------------------------- /ch15/ex15.28.29/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= quantity ? 1 - discount : 1); 6 | } 7 | 8 | void Bulk_quote::debug() const 9 | { 10 | std::cout //<< "data members of this class:\n" 11 | << "min_qty= " << quantity << " " 12 | << "discount= " << this->discount<< " \n"; 13 | } 14 | -------------------------------------------------------------------------------- /ch15/ex15.28.29/disc_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "disc_quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.28.29/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | void Limit_quote::debug() const 5 | { 6 | std::cout //<< "data members of this class:\n" 7 | << "max_qty= " << this->quantity << " " 8 | << "discount= " << this->discount<< " \n"; 9 | } 10 | -------------------------------------------------------------------------------- /ch15/ex15.28.29/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "disc_quote.h" 5 | 6 | class Limit_quote : public Disc_quote 7 | { 8 | public: 9 | Limit_quote() = default; 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Disc_quote(b,p,max,disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price * (n < quantity ? 1 - discount : 1 ); } 15 | 16 | void debug() const override; 17 | }; 18 | 19 | #endif // LIMIT_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.28.29/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | void Quote::debug() const 4 | { 5 | std::cout //<< "data members of this class:\n" 6 | << "bookNo= " <bookNo << " " 7 | << "price= " <price<< " \n"; 8 | } 9 | -------------------------------------------------------------------------------- /ch15/ex15.30/basket.cpp: -------------------------------------------------------------------------------- 1 | #include "basket.h" 2 | double Basket::total_receipt(std::ostream &os) const 3 | { 4 | double sum = 0.0; 5 | 6 | for(auto iter = items.cbegin(); iter != items.cend(); 7 | iter = items.upper_bound(*iter)) 8 | //! ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 9 | //! @note this increment moves iter to the first element with key 10 | //! greater than *iter. 11 | 12 | { 13 | sum += print_total(os, **iter, items.count(*iter)); 14 | } //! ^^^^^^^^^^^^^ using count to fetch 15 | //! the number of the same book. 16 | os << "Total Sale: " << sum << std::endl; 17 | return sum; 18 | } 19 | -------------------------------------------------------------------------------- /ch15/ex15.30/basket.h: -------------------------------------------------------------------------------- 1 | #ifndef BASKET_H 2 | #define BASKET_H 3 | 4 | #include "quote.h" 5 | #include 6 | #include 7 | 8 | 9 | //! a basket of objects from Quote hierachy, using smart pointers. 10 | class Basket 11 | { 12 | public: 13 | //! copy verison 14 | void add_item(const Quote& sale) 15 | { items.insert(std::shared_ptr(sale.clone())); } 16 | //! move version 17 | void add_item(Quote&& sale) 18 | { items.insert(std::shared_ptr(std::move(sale).clone())); } 19 | 20 | double total_receipt(std::ostream& os) const; 21 | 22 | private: 23 | 24 | //! function to compare needed by the multiset member 25 | static bool compare(const std::shared_ptr& lhs, 26 | const std::shared_ptr& rhs) 27 | { return lhs->isbn() < rhs->isbn(); } 28 | 29 | //! hold multiple quotes, ordered by the compare member 30 | std::multiset, decltype(compare)*> 31 | items{compare}; 32 | }; 33 | 34 | #endif // BASKET_H 35 | -------------------------------------------------------------------------------- /ch15/ex15.30/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= quantity ? 1 - discount : 1); 6 | } 7 | 8 | void Bulk_quote::debug() const 9 | { 10 | std::cout //<< "data members of this class:\n" 11 | << "min_qty= " << quantity << " " 12 | << "discount= " << this->discount<< " \n"; 13 | } 14 | -------------------------------------------------------------------------------- /ch15/ex15.30/disc_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "disc_quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.30/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | void Limit_quote::debug() const 5 | { 6 | std::cout //<< "data members of this class:\n" 7 | << "max_qty= " << this->quantity << " " 8 | << "discount= " << this->discount<< " \n"; 9 | } 10 | -------------------------------------------------------------------------------- /ch15/ex15.30/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "disc_quote.h" 5 | 6 | class Limit_quote : public Disc_quote 7 | { 8 | public: 9 | Limit_quote() = default; 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Disc_quote(b,p,max,disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price * (n < quantity ? 1 - discount : 1 ); } 15 | 16 | void debug() const override; 17 | }; 18 | 19 | #endif // LIMIT_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.30/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | void Quote::debug() const 4 | { 5 | std::cout //<< "data members of this class:\n" 6 | << "bookNo= " <bookNo << " " 7 | << "price= " <price<< " \n"; 8 | } 9 | 10 | //! non-member 11 | double print_total(std::ostream &os,const Quote &item, size_t n) 12 | { 13 | // depending on the type of the object bound to the item parameter 14 | // calls either Quote::net_price or Bulk_quote::net_price 15 | double ret = item.net_price(n); 16 | os << "ISBN: " << item.isbn() // calls Quote::isbn 17 | << " # sold: " << n << " total due: " << ret << std::endl; 18 | return ret; 19 | } 20 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include "andquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ANDQUERY_H 2 | #define ANDQUERY_H 3 | 4 | 5 | #include "binaryquery.h" 6 | 7 | class AndQuery : public BinaryQuery 8 | { 9 | friend Query operator&(const Query&, const Query&); 10 | AndQuery(const Query& left, const Query& right): 11 | BinaryQuery(left,right, "&") 12 | { 13 | std::cout << "AndQuery::AndQuery()\n"; 14 | } 15 | 16 | //! @note: inherits rep and define eval 17 | 18 | QueryResult eval(const TextQuery &) const override 19 | { 20 | // this is just a placeholder rather than the real definition 21 | } 22 | }; 23 | 24 | inline Query operator& (const Query& lhs, const Query& rhs) 25 | { 26 | return std::shared_ptr(new AndQuery(lhs,rhs)); 27 | } 28 | 29 | #endif // ANDQUERY_H 30 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include "binaryquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARYQUERY_H 2 | #define BINARYQUERY_H 3 | 4 | #include "query_base.h" 5 | #include "query.h" 6 | 7 | 8 | 9 | /** 10 | * @brief The BinaryQuery class 11 | *An abstract class holds data needed by the query types that operate on two operands 12 | */ 13 | class BinaryQuery : public Query_base 14 | { 15 | protected: 16 | BinaryQuery(const Query&l, const Query& r, std::string s): 17 | lhs(l), rhs(r), opSym(s) 18 | { 19 | std::cout << "BinaryQuery::BinaryQuery() where s=" + s + "\n"; 20 | } 21 | 22 | //! @note: abstract class: BinaryQuery doesn't define eval 23 | 24 | std::string rep() const override 25 | { 26 | std::cout << "BinaryQuery::rep()\n"; 27 | return "(" + lhs.rep() + " " 28 | + opSym + " " 29 | + rhs.rep() + ")"; 30 | } 31 | 32 | Query lhs, rhs; 33 | std::string opSym; 34 | }; 35 | 36 | #endif // BINARYQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include "notquery.h" 2 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include "orquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ORQUERY_H 2 | #define ORQUERY_H 3 | 4 | #include "binaryquery.h" 5 | 6 | class OrQuery :public BinaryQuery 7 | { 8 | friend Query operator|(const Query&, const Query&); 9 | OrQuery(const Query& left, const Query& right): 10 | BinaryQuery(left, right, "|") 11 | { 12 | std::cout << "OrQuery::OrQuery\n"; 13 | } 14 | 15 | QueryResult eval(const TextQuery& )const override 16 | { 17 | //place holder 18 | } 19 | }; 20 | 21 | inline Query operator|(const Query &lhs, const Query& rhs) 22 | { 23 | return std::shared_ptr(new OrQuery(lhs, rhs)); 24 | } 25 | 26 | #endif // ORQUERY_H 27 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/query.cpp: -------------------------------------------------------------------------------- 1 | #include "query.h" 2 | 3 | 4 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include "query_base.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/query_base.h: -------------------------------------------------------------------------------- 1 | #ifndef QUERY_BASE_H 2 | #define QUERY_BASE_H 3 | #include "textquery.h" 4 | #include "queryresult.h" 5 | 6 | /** 7 | * @brief abstract class acts as a base class for all concrete query types 8 | * all members are private. 9 | */ 10 | class Query_base 11 | { 12 | friend class Query; 13 | protected: 14 | using line_no = TextQuery::line_no; // used in the eval function 15 | virtual ~Query_base() = default; 16 | 17 | private: 18 | //! returns QueryResult that matches this query 19 | virtual QueryResult eval(const TextQuery&) const = 0; 20 | 21 | //! a string representation of this query 22 | virtual std::string rep() const = 0; 23 | }; 24 | 25 | #endif // QUERY_BASE_H 26 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/queryresult.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file queryresult.cpp 3 | * @author Alan.W 4 | * @date 30 DEC 2013 5 | * @remark using class StrBlob 6 | ***************************************************************************/ 7 | 8 | 9 | #include "queryresult.h" 10 | 11 | 12 | /** 13 | * @brief print the result to the output stream specified. 14 | * @note class QueryResult's friend 15 | */ 16 | std::ostream 17 | &print(std::ostream &os, const QueryResult &qr) 18 | { 19 | os << qr.sought << " occurs " << qr.sp_lines->size() << " " 20 | << "times" << "\n"; 21 | 22 | //! print each line in which the word appears 23 | for ( auto &index : *qr.sp_lines) 24 | { 25 | os << "\t(line " << index + 1 << ") "; 26 | const StrBlobPtr wp(qr.file, index); 27 | os << wp.deref() << "\n"; 28 | } 29 | return os; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include "wordquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.34.35.36.38/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef WORDQUERY_H 2 | #define WORDQUERY_H 3 | 4 | #include "query_base.h" 5 | 6 | /** 7 | * @brief The WordQuery class 8 | *The only class that actually performs a query on the given TextQuery object. 9 | *No public members defined in this class. All operation are through the friend 10 | *class Query. 11 | */ 12 | class WordQuery : public Query_base 13 | { 14 | //! class Query uses the WordQuery constructor 15 | friend class Query; 16 | WordQuery(const std::string& s): 17 | query_word(s) 18 | { 19 | std::cout << "WordQuery::WordQuery(" + s + ")\n"; 20 | } 21 | 22 | 23 | //! virtuals: 24 | QueryResult eval(const TextQuery& t) const override 25 | { return t.query(query_word); } 26 | std::string rep() const override 27 | { 28 | std::cout << "WodQuery::rep()\n"; 29 | return query_word; 30 | } 31 | 32 | 33 | std::string query_word; 34 | }; 35 | 36 | #endif // WORDQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include "andquery.h" 2 | #include 3 | #include 4 | /** 5 | * @brief AndQuery::eval 6 | * @return the intersection of its operands' result sets 7 | */ 8 | QueryResult AndQuery::eval(const TextQuery &text) const 9 | { 10 | //! virtual calls through the Query operands to get result sets for the operands 11 | QueryResult left = lhs.eval(text), right = rhs.eval(text); 12 | 13 | //! set to hold the intersection of the left and right 14 | std::shared_ptr> 15 | ret_lines = std::make_shared>(); 16 | 17 | //! writes the intersection of two ranges to a destination iterator 18 | std::set_intersection(left.begin(), left.end(), 19 | right.begin(), right.end(), 20 | std::inserter(*ret_lines, ret_lines->begin())); 21 | 22 | return QueryResult(rep(), ret_lines, left.get_file()); 23 | } 24 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ANDQUERY_H 2 | #define ANDQUERY_H 3 | 4 | 5 | #include "binaryquery.h" 6 | 7 | class AndQuery : public BinaryQuery 8 | { 9 | friend Query operator&(const Query&, const Query&); 10 | AndQuery(const Query& left, const Query& right): 11 | BinaryQuery(left,right, "&") 12 | { 13 | std::cout << "AndQuery::AndQuery()\n"; 14 | } 15 | 16 | //! @note: inherits rep and define eval 17 | 18 | QueryResult eval(const TextQuery &) const override; 19 | }; 20 | 21 | inline Query operator& (const Query& lhs, const Query& rhs) 22 | { 23 | return std::shared_ptr(new AndQuery(lhs,rhs)); 24 | } 25 | 26 | #endif // ANDQUERY_H 27 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include "binaryquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARYQUERY_H 2 | #define BINARYQUERY_H 3 | 4 | #include "query_base.h" 5 | #include "query.h" 6 | 7 | 8 | 9 | /** 10 | * @brief The BinaryQuery class 11 | *An abstract class holds data needed by the query types that operate on two operands 12 | */ 13 | class BinaryQuery : public Query_base 14 | { 15 | protected: 16 | BinaryQuery(const Query&l, const Query& r, std::string s): 17 | lhs(l), rhs(r), opSym(s) 18 | { 19 | std::cout << "BinaryQuery::BinaryQuery() where s=" + s + "\n"; 20 | } 21 | 22 | //! @note: abstract class: BinaryQuery doesn't define eval 23 | 24 | std::string rep() const override 25 | { 26 | std::cout << "BinaryQuery::rep()\n"; 27 | return "(" + lhs.rep() + " " 28 | + opSym + " " 29 | + rhs.rep() + ")"; 30 | } 31 | 32 | Query lhs, rhs; 33 | std::string opSym; 34 | }; 35 | 36 | #endif // BINARYQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include "notquery.h" 2 | #include 3 | /** 4 | * @brief NotQuery::eval 5 | * @return the lines not in its operand's result set 6 | */ 7 | QueryResult NotQuery::eval(const TextQuery &text) const 8 | { 9 | //! virtual call to eval through the Query operand 10 | QueryResult result = query.eval(text); 11 | 12 | //! start out with an empty result set 13 | std::shared_ptr> 14 | ret_lines = std::make_shared>(); 15 | 16 | std::set::iterator 17 | begin = result.begin(), 18 | end = result.end(); 19 | 20 | StrBlob::size_type sz = result.get_file().size(); 21 | 22 | for(std::size_t n = 0; n != sz; ++n) 23 | { 24 | if(begin == end || *begin != n) 25 | ret_lines->insert(n); 26 | else if (begin != end) 27 | ++begin; 28 | } 29 | 30 | return QueryResult(rep(), ret_lines, result.get_file()); 31 | } 32 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "orquery.h" 3 | 4 | 5 | QueryResult OrQuery::eval(const TextQuery &text) const 6 | { 7 | QueryResult right = rhs.eval(text), left= lhs.eval(text); 8 | 9 | //! copy the left-hand operand into the result set 10 | std::shared_ptr> ret_lines = 11 | std::make_shared>(left.begin(), left.end()); 12 | 13 | //! inert lines from the right-hand operand 14 | ret_lines->insert(right.begin(), right.end()); 15 | 16 | return QueryResult(rep(),ret_lines,left.get_file()); 17 | } 18 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef ORQUERY_H 2 | #define ORQUERY_H 3 | 4 | #include "binaryquery.h" 5 | 6 | class OrQuery :public BinaryQuery 7 | { 8 | friend Query operator|(const Query&, const Query&); 9 | OrQuery(const Query& left, const Query& right): 10 | BinaryQuery(left, right, "|") 11 | { 12 | std::cout << "OrQuery::OrQuery\n"; 13 | } 14 | 15 | QueryResult eval(const TextQuery& )const override; 16 | }; 17 | 18 | inline Query operator|(const Query &lhs, const Query& rhs) 19 | { 20 | return std::shared_ptr(new OrQuery(lhs, rhs)); 21 | } 22 | 23 | #endif // ORQUERY_H 24 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/query.cpp: -------------------------------------------------------------------------------- 1 | #include "query.h" 2 | 3 | 4 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include "query_base.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/query_base.h: -------------------------------------------------------------------------------- 1 | #ifndef QUERY_BASE_H 2 | #define QUERY_BASE_H 3 | #include "textquery.h" 4 | #include "queryresult.h" 5 | 6 | /** 7 | * @brief abstract class acts as a base class for all concrete query types 8 | * all members are private. 9 | */ 10 | class Query_base 11 | { 12 | friend class Query; 13 | protected: 14 | using line_no = TextQuery::line_no; // used in the eval function 15 | virtual ~Query_base() = default; 16 | 17 | private: 18 | //! returns QueryResult that matches this query 19 | virtual QueryResult eval(const TextQuery&) const = 0; 20 | 21 | //! a string representation of this query 22 | virtual std::string rep() const = 0; 23 | }; 24 | 25 | #endif // QUERY_BASE_H 26 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/queryresult.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file queryresult.cpp 3 | * @author Alan.W 4 | * @date 30 DEC 2013 5 | * @remark using class StrBlob 6 | ***************************************************************************/ 7 | 8 | 9 | #include "queryresult.h" 10 | 11 | 12 | /** 13 | * @brief print the result to the output stream specified. 14 | * @note class QueryResult's friend 15 | */ 16 | std::ostream& 17 | operator <<(std::ostream &os, const QueryResult &qr) 18 | { 19 | os << qr.sought << " occurs " << qr.sp_lines->size() << " " 20 | << "times" << "\n"; 21 | 22 | //! print each line in which the word appears 23 | for ( auto &index : *qr.sp_lines) 24 | { 25 | os << "\t(line " << index + 1 << ") "; 26 | const StrBlobPtr wp(qr.file, index); 27 | os << wp.deref() << "\n"; 28 | } 29 | return os; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include "wordquery.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.39.40/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef WORDQUERY_H 2 | #define WORDQUERY_H 3 | 4 | #include "query_base.h" 5 | 6 | /** 7 | * @brief The WordQuery class 8 | *The only class that actually performs a query on the given TextQuery object. 9 | *No public members defined in this class. All operation are through the friend 10 | *class Query. 11 | */ 12 | class WordQuery : public Query_base 13 | { 14 | //! class Query uses the WordQuery constructor 15 | friend class Query; 16 | WordQuery(const std::string& s): 17 | query_word(s) 18 | { 19 | std::cout << "WordQuery::WordQuery(" + s + ")\n"; 20 | } 21 | 22 | 23 | //! virtuals: 24 | QueryResult eval(const TextQuery& t) const override 25 | { return t.query(query_word); } 26 | std::string rep() const override 27 | { 28 | std::cout << "WodQuery::rep()\n"; 29 | return query_word; 30 | } 31 | 32 | 33 | std::string query_word; 34 | }; 35 | 36 | #endif // WORDQUERY_H 37 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include"andquery.h" 2 | 3 | #include 4 | using std::set_intersection; 5 | 6 | #include 7 | using std::inserter; 8 | 9 | #include 10 | using std::make_shared; 11 | 12 | #include 13 | using std::set; 14 | 15 | #include"queryresult.h" 16 | #include"textquery.h" 17 | #include"query.h" 18 | 19 | QueryResult 20 | AndQuery::eval(const TextQuery& text) const 21 | { 22 | auto left = lhs.eval(text); 23 | auto right = rhs.eval(text); 24 | 25 | auto ret_lines = make_shared>(); 26 | 27 | set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin())); 28 | 29 | return QueryResult(rep(), ret_lines, left.get_file()); 30 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ANDQUERY_H 2 | #define _ANDQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class AndQuery :public BinaryQuery 14 | { 15 | friend Query operator&(const Query&, const Query&); 16 | AndQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "&"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator&(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new AndQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include"binaryquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_b/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINARYQUERY_H 2 | #define _BINARYQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query.h" 8 | #include"query_base.h" 9 | 10 | 11 | class BinaryQuery :public Query_base 12 | { 13 | protected: 14 | BinaryQuery(const Query &l, const Query &r, string s) :lhs(l), rhs(r), opSym(s){} 15 | string rep() const 16 | { 17 | return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; 18 | } 19 | 20 | Query lhs, rhs; 21 | string opSym; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; using std::cin; using std::endl; 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include"queryhistory.h" 14 | #include"queryresult.h" 15 | #include"textquery.h" 16 | #include"query.h" 17 | #include"andquery.h" 18 | #include"orquery.h" 19 | #include"notquery.h" 20 | 21 | int main() 22 | { 23 | ifstream fin("test.txt"); 24 | TextQuery text(fin); 25 | QueryHistory history; 26 | Query q0("Alice"); 27 | Query q1("hair"); 28 | Query q2("Daddy"); 29 | 30 | history.add_query(q0); 31 | history.add_query(q1); 32 | history[0] = history[0] | q2; 33 | 34 | auto result = history[0].eval(text); 35 | print(cout, result); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include"notquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | 14 | QueryResult 15 | NotQuery::eval(const TextQuery &text) const 16 | { 17 | auto result = query.eval(text); 18 | 19 | auto ret_lines = make_shared>(); 20 | 21 | auto beg = result.begin(); 22 | auto end = result.end(); 23 | 24 | auto sz = result.get_file()->size(); 25 | for (size_t n = 0; n != sz; ++n) 26 | { 27 | if (beg == end || *beg != n) 28 | ret_lines->insert(n); 29 | else if (beg != end) 30 | ++beg; 31 | } 32 | return QueryResult(rep(), ret_lines, result.get_file()); 33 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/notquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _NOTQUERY_H 2 | #define _NOTQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include"query.h" 11 | #include"query_base.h" 12 | 13 | class QueryResult; 14 | class TextQuery; 15 | 16 | class NotQuery :public Query_base 17 | { 18 | friend Query operator~(const Query&); 19 | //call Query's default copy constructor. 20 | NotQuery(const Query &q) :query(q){} 21 | string rep() const{ return "~(" + query.rep() + ")"; } 22 | QueryResult eval(const TextQuery&) const; 23 | 24 | Query query; 25 | }; 26 | 27 | inline Query operator~(const Query &operand) 28 | { 29 | return shared_ptr(new NotQuery(operand)); 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include"orquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | QueryResult 14 | OrQuery::eval(const TextQuery &text) const 15 | { 16 | auto right = rhs.eval(text); 17 | auto left = lhs.eval(text); 18 | auto ret_lines = make_shared>(left.begin(), left.end()); 19 | ret_lines->insert(right.begin(), right.end()); 20 | return QueryResult(rep(), ret_lines, left.get_file()); 21 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ORQUERY_H 2 | #define _ORQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class OrQuery :public BinaryQuery 14 | { 15 | friend Query operator|(const Query&, const Query&); 16 | OrQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "|"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator|(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new OrQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/query.cpp: -------------------------------------------------------------------------------- 1 | #include"query.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | operator<<(ostream &os, const Query &query) 8 | { 9 | return os << query.rep(); 10 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/query.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_H 2 | #define _QUERY_H 3 | 4 | #include 5 | using std::ostream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::string; 12 | 13 | #include"query_base.h" 14 | #include"queryresult.h" 15 | #include"wordquery.h" 16 | 17 | 18 | class TextQuery; 19 | 20 | class Query 21 | { 22 | friend Query operator~(const Query&); 23 | friend Query operator|(const Query&, const Query&); 24 | friend Query operator&(const Query&, const Query&); 25 | public: 26 | Query(const string&); 27 | //call QueryResult's default copy constructor. 28 | QueryResult eval(const TextQuery &t) const { return q->eval(t); } 29 | string rep() const { return q->rep(); } 30 | private: 31 | Query(shared_ptr query) :q(query){} 32 | shared_ptr q; 33 | }; 34 | 35 | ostream & operator<<(ostream &os, const Query &query); 36 | 37 | inline Query::Query(const string &s) :q(new WordQuery(s)){} 38 | 39 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include"query_base.h" -------------------------------------------------------------------------------- /ch15/ex15.42_b/query_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_BASE_H 2 | #define _QUERY_BASE_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"textquery.h" 8 | 9 | class Query_base 10 | { 11 | friend class Query; 12 | protected: 13 | using line_no = TextQuery::line_no; 14 | virtual ~Query_base() = default; 15 | private: 16 | virtual QueryResult eval(const TextQuery&) const = 0; 17 | virtual string rep() const = 0; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryhistory.cpp: -------------------------------------------------------------------------------- 1 | #include"queryhistory.h" 2 | 3 | #include 4 | using std::shared_ptr; using std::make_shared; 5 | 6 | size_t QueryHistory::add_query(const Query &query) 7 | { 8 | shared_ptr p = make_shared(query); 9 | query_vec.push_back(p); 10 | return query_vec.size() - 1; 11 | } -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryhistory.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERYHISTORY_H 2 | #define _QUERYHISTORY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include 8 | using std::vector; 9 | 10 | #include"query.h" 11 | 12 | class QueryHistory 13 | { 14 | public: 15 | Query& operator[](size_t n) 16 | { 17 | return *(query_vec[n]); 18 | } 19 | 20 | //return the assigned number of the new query 21 | size_t add_query(const Query&); 22 | private: 23 | vector> query_vec; 24 | }; 25 | 26 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryresult.cpp: -------------------------------------------------------------------------------- 1 | #include "queryresult.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | print(ostream &os, const QueryResult &qr) 8 | { 9 | os <<"The result of your query "<< qr.sought <<" is: \n"; 10 | for (const auto &index: *qr.lines) 11 | os << "\t(line " << index + 1 << ")" 12 | << *(qr.file->begin() + index) << "\n"; 13 | return os; 14 | } 15 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/queryresult.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERYRESULT_H 2 | #define _QUERYRESULT_H 3 | 4 | #include 5 | using std::ostream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::set; 12 | 13 | #include 14 | using std::vector; 15 | 16 | #include 17 | using std::string; 18 | 19 | #include "textquery.h" 20 | 21 | 22 | class QueryResult 23 | { 24 | friend ostream& print(ostream&, const QueryResult&); 25 | 26 | public: 27 | QueryResult(string s, 28 | shared_ptr> l, 29 | shared_ptr> f) : 30 | sought(s), lines(l), file(f){} 31 | 32 | set::iterator begin(){ return lines->begin(); } 33 | set::iterator end(){ return lines->end(); } 34 | shared_ptr> get_file(){ return file; } 35 | 36 | private: 37 | string sought; 38 | shared_ptr> lines; 39 | shared_ptr> file; 40 | }; 41 | 42 | ostream& 43 | print(ostream&, const QueryResult&); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/test.txt: -------------------------------------------------------------------------------- 1 | Alice Emma has long flowing red hair. 2 | Her Daddy says when the wind blows 3 | through her hair, it looks almost alive, 4 | like a fiery bird in flight. 5 | A beautiful fiery bird, he tells her, 6 | magical but untamed. 7 | "Daddy, shush, there is no such thing," 8 | she tells him, at the same time wanting 9 | him to tell her more. 10 | Shyly, she asks, "I mean, Daddy, is there?" -------------------------------------------------------------------------------- /ch15/ex15.42_b/textquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEXTQUERY_H 2 | #define _TEXTQUERY_H 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include 14 | using std::string; 15 | 16 | #include 17 | using std::map; 18 | 19 | #include 20 | using std::set; 21 | 22 | class QueryResult; 23 | 24 | class TextQuery 25 | { 26 | 27 | public: 28 | typedef vector::size_type line_no; 29 | 30 | TextQuery(ifstream&); 31 | QueryResult query(const string&) const; 32 | 33 | private: 34 | shared_ptr> file; 35 | map>> wm; 36 | 37 | shared_ptr> handlePunct(const string&); 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ch15/ex15.42_b/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include"wordquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_b/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _WORDQUERY_H 2 | #define _WORDQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query_base.h" 8 | #include"queryresult.h" 9 | #include"textquery.h" 10 | 11 | class WordQuery:public Query_base 12 | { 13 | friend class Query; 14 | WordQuery(const string &s) :query_word(s){} 15 | QueryResult eval(const TextQuery &t) const{ return t.query(query_word); } 16 | string rep() const { return query_word; } 17 | 18 | string query_word; 19 | }; 20 | 21 | 22 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/andquery.cpp: -------------------------------------------------------------------------------- 1 | #include"andquery.h" 2 | 3 | #include 4 | using std::set_intersection; 5 | 6 | #include 7 | using std::inserter; 8 | 9 | #include 10 | using std::make_shared; 11 | 12 | #include 13 | using std::set; 14 | 15 | #include"queryresult.h" 16 | #include"textquery.h" 17 | #include"query.h" 18 | 19 | QueryResult 20 | AndQuery::eval(const TextQuery& text) const 21 | { 22 | auto left = lhs.eval(text); 23 | auto right = rhs.eval(text); 24 | 25 | auto ret_lines = make_shared>(); 26 | 27 | set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin())); 28 | 29 | return QueryResult(rep(), ret_lines, left.get_file()); 30 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/andquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ANDQUERY_H 2 | #define _ANDQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class AndQuery :public BinaryQuery 14 | { 15 | friend Query operator&(const Query&, const Query&); 16 | AndQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "&"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator&(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new AndQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/binaryquery.cpp: -------------------------------------------------------------------------------- 1 | #include"binaryquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_c/binaryquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _BINARYQUERY_H 2 | #define _BINARYQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query.h" 8 | #include"query_base.h" 9 | 10 | 11 | class BinaryQuery :public Query_base 12 | { 13 | protected: 14 | BinaryQuery(const Query &l, const Query &r, string s) :lhs(l), rhs(r), opSym(s){} 15 | string rep() const 16 | { 17 | return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; 18 | } 19 | 20 | Query lhs, rhs; 21 | string opSym; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::cout; using std::cin; using std::endl; 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include"queryresult.h" 14 | #include"textquery.h" 15 | #include"query.h" 16 | #include"andquery.h" 17 | #include"orquery.h" 18 | #include"notquery.h" 19 | 20 | int main() 21 | { 22 | ifstream fin("test.txt"); 23 | TextQuery text(fin); 24 | auto q = ~Query("Alice"); 25 | 26 | auto result = q.eval(text); 27 | print(cout, result); 28 | cout << endl; 29 | print(cout, result, -3, 5); 30 | cout << endl; 31 | print(cout, result, 3, 5); 32 | cout << endl; 33 | print(cout, result, 3, 20); 34 | cout << endl; 35 | 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /ch15/ex15.42_c/notquery.cpp: -------------------------------------------------------------------------------- 1 | #include"notquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | 14 | QueryResult 15 | NotQuery::eval(const TextQuery &text) const 16 | { 17 | auto result = query.eval(text); 18 | 19 | auto ret_lines = make_shared>(); 20 | 21 | auto beg = result.begin(); 22 | auto end = result.end(); 23 | 24 | auto sz = result.get_file()->size(); 25 | for (size_t n = 0; n != sz; ++n) 26 | { 27 | if (beg == end || *beg != n) 28 | ret_lines->insert(n); 29 | else if (beg != end) 30 | ++beg; 31 | } 32 | return QueryResult(rep(), ret_lines, result.get_file()); 33 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/notquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _NOTQUERY_H 2 | #define _NOTQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include 8 | using std::string; 9 | 10 | #include"query.h" 11 | #include"query_base.h" 12 | 13 | class QueryResult; 14 | class TextQuery; 15 | 16 | class NotQuery :public Query_base 17 | { 18 | friend Query operator~(const Query&); 19 | //call Query's default copy constructor. 20 | NotQuery(const Query &q) :query(q){} 21 | string rep() const{ return "~(" + query.rep() + ")"; } 22 | QueryResult eval(const TextQuery&) const; 23 | 24 | Query query; 25 | }; 26 | 27 | inline Query operator~(const Query &operand) 28 | { 29 | return shared_ptr(new NotQuery(operand)); 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/orquery.cpp: -------------------------------------------------------------------------------- 1 | #include"orquery.h" 2 | 3 | #include 4 | using std::make_shared; 5 | 6 | #include 7 | using std::set; 8 | 9 | #include"queryresult.h" 10 | #include"textquery.h" 11 | #include"query.h" 12 | 13 | QueryResult 14 | OrQuery::eval(const TextQuery &text) const 15 | { 16 | auto right = rhs.eval(text); 17 | auto left = lhs.eval(text); 18 | auto ret_lines = make_shared>(left.begin(), left.end()); 19 | ret_lines->insert(right.begin(), right.end()); 20 | return QueryResult(rep(), ret_lines, left.get_file()); 21 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/orquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _ORQUERY_H 2 | #define _ORQUERY_H 3 | 4 | #include 5 | using std::shared_ptr; 6 | 7 | #include"query.h" 8 | #include"binaryquery.h" 9 | 10 | class QueryResult; 11 | class TextQuery; 12 | 13 | class OrQuery :public BinaryQuery 14 | { 15 | friend Query operator|(const Query&, const Query&); 16 | OrQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "|"){} 17 | QueryResult eval(const TextQuery&) const; 18 | }; 19 | 20 | inline Query operator|(const Query &lhs, const Query &rhs) 21 | { 22 | return shared_ptr(new OrQuery(lhs, rhs)); 23 | } 24 | 25 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/query.cpp: -------------------------------------------------------------------------------- 1 | #include"query.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | operator<<(ostream &os, const Query &query) 8 | { 9 | return os << query.rep(); 10 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/query.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_H 2 | #define _QUERY_H 3 | 4 | #include 5 | using std::ostream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::string; 12 | 13 | #include"query_base.h" 14 | #include"queryresult.h" 15 | #include"wordquery.h" 16 | 17 | 18 | class TextQuery; 19 | 20 | class Query 21 | { 22 | friend Query operator~(const Query&); 23 | friend Query operator|(const Query&, const Query&); 24 | friend Query operator&(const Query&, const Query&); 25 | public: 26 | Query(const string&); 27 | //call QueryResult's default copy constructor. 28 | QueryResult eval(const TextQuery &t) const { return q->eval(t); } 29 | string rep() const { return q->rep(); } 30 | private: 31 | Query(shared_ptr query) :q(query){} 32 | shared_ptr q; 33 | }; 34 | 35 | ostream & operator<<(ostream &os, const Query &query); 36 | 37 | inline Query::Query(const string &s) :q(new WordQuery(s)){} 38 | 39 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/query_base.cpp: -------------------------------------------------------------------------------- 1 | #include"query_base.h" -------------------------------------------------------------------------------- /ch15/ex15.42_c/query_base.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUERY_BASE_H 2 | #define _QUERY_BASE_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"textquery.h" 8 | 9 | class Query_base 10 | { 11 | friend class Query; 12 | protected: 13 | using line_no = TextQuery::line_no; 14 | virtual ~Query_base() = default; 15 | private: 16 | virtual QueryResult eval(const TextQuery&) const = 0; 17 | virtual string rep() const = 0; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /ch15/ex15.42_c/queryresult.cpp: -------------------------------------------------------------------------------- 1 | #include "queryresult.h" 2 | 3 | #include 4 | using std::ostream; 5 | 6 | ostream& 7 | print(ostream &os, const QueryResult &qr) 8 | { 9 | os <<"The result of your query "<< qr.sought <<" is: \n"; 10 | for (const auto &index: *qr.lines) 11 | os << "\t(line " << index + 1 << ")" 12 | << *(qr.file->begin() + index) << "\n"; 13 | return os; 14 | } 15 | 16 | /* 17 | Head is the first line of the range. 18 | Trail is the last line of the range. 19 | */ 20 | ostream& 21 | print(ostream& os, const QueryResult &qr,size_t head, size_t trail) 22 | { 23 | if (head > trail) 24 | { 25 | os << "illegal range!\n"; 26 | return os; 27 | } 28 | else 29 | { 30 | os << "The result of your query " << qr.sought << " is: \n"; 31 | for (const auto &index : *qr.lines) 32 | { 33 | if (index + 1 >= head&&index + 1 <= trail) 34 | { 35 | os << "\t(line " << index + 1 << ")" 36 | << *(qr.file->begin() + index) << "\n"; 37 | } 38 | } 39 | return os; 40 | } 41 | } -------------------------------------------------------------------------------- /ch15/ex15.42_c/test.txt: -------------------------------------------------------------------------------- 1 | Alice Emma has long flowing red hair. 2 | Her Daddy says when the wind blows 3 | through her hair, it looks almost alive, 4 | like a fiery bird in flight. 5 | A beautiful fiery bird, he tells her, 6 | magical but untamed. 7 | "Daddy, shush, there is no such thing," 8 | she tells him, at the same time wanting 9 | him to tell her more. 10 | Shyly, she asks, "I mean, Daddy, is there?" -------------------------------------------------------------------------------- /ch15/ex15.42_c/textquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEXTQUERY_H 2 | #define _TEXTQUERY_H 3 | 4 | #include 5 | using std::ifstream; 6 | 7 | #include 8 | using std::shared_ptr; 9 | 10 | #include 11 | using std::vector; 12 | 13 | #include 14 | using std::string; 15 | 16 | #include 17 | using std::map; 18 | 19 | #include 20 | using std::set; 21 | 22 | class QueryResult; 23 | 24 | class TextQuery 25 | { 26 | 27 | public: 28 | typedef vector::size_type line_no; 29 | 30 | TextQuery(ifstream&); 31 | QueryResult query(const string&) const; 32 | 33 | private: 34 | shared_ptr> file; 35 | map>> wm; 36 | 37 | shared_ptr> handlePunct(const string&); 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /ch15/ex15.42_c/wordquery.cpp: -------------------------------------------------------------------------------- 1 | #include"wordquery.h" -------------------------------------------------------------------------------- /ch15/ex15.42_c/wordquery.h: -------------------------------------------------------------------------------- 1 | #ifndef _WORDQUERY_H 2 | #define _WORDQUERY_H 3 | 4 | #include 5 | using std::string; 6 | 7 | #include"query_base.h" 8 | #include"queryresult.h" 9 | #include"textquery.h" 10 | 11 | class WordQuery:public Query_base 12 | { 13 | friend class Query; 14 | WordQuery(const string &s) :query_word(s){} 15 | QueryResult eval(const TextQuery &t) const{ return t.query(query_word); } 16 | string rep() const { return query_word; } 17 | 18 | string query_word; 19 | }; 20 | 21 | 22 | #endif -------------------------------------------------------------------------------- /ch15/ex15.5.6/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= min_qty ? 1 - discount : 1); 6 | } 7 | -------------------------------------------------------------------------------- /ch15/ex15.5.6/bulk_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include 4 | 5 | class Bulk_quote : public Quote 6 | { 7 | public: 8 | Bulk_quote() = default; 9 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 10 | Quote(b,p), min_qty(q), discount(disc) { } 11 | 12 | double net_price(std::size_t n) const override; 13 | 14 | private: 15 | std::size_t min_qty = 0; 16 | double discount = 0.0; 17 | }; 18 | 19 | #endif // BULK_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.5.6/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.5.6/quote.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | 6 | class Quote 7 | { 8 | public: 9 | Quote() = default; 10 | Quote(const std::string &b, double p) : 11 | bookNo(b), price(p) { } 12 | 13 | std::string isbn() const { return bookNo; } 14 | virtual double net_price(std::size_t n) const { return n * price; } 15 | 16 | virtual ~Quote() = default; 17 | 18 | private: 19 | std::string bookNo; 20 | 21 | protected: 22 | double price = 0.0; 23 | 24 | }; 25 | 26 | #endif // QUOTE_H 27 | -------------------------------------------------------------------------------- /ch15/ex15.7/bulk_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "bulk_quote.h" 2 | 3 | double Bulk_quote::net_price(std::size_t n) const 4 | { 5 | return n * price * ( n >= min_qty ? 1 - discount : 1); 6 | } 7 | -------------------------------------------------------------------------------- /ch15/ex15.7/bulk_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef BULK_QUOTE_H 2 | #define BULK_QUOTE_H 3 | #include 4 | 5 | class Bulk_quote : public Quote 6 | { 7 | public: 8 | Bulk_quote() = default; 9 | Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : 10 | Quote(b,p), min_qty(q), discount(disc) { } 11 | 12 | double net_price(std::size_t n) const override; 13 | 14 | private: 15 | std::size_t min_qty = 0; 16 | double discount = 0.0; 17 | }; 18 | 19 | #endif // BULK_QUOTE_H 20 | -------------------------------------------------------------------------------- /ch15/ex15.7/limit_quote.cpp: -------------------------------------------------------------------------------- 1 | #include "limit_quote.h" 2 | 3 | 4 | -------------------------------------------------------------------------------- /ch15/ex15.7/limit_quote.h: -------------------------------------------------------------------------------- 1 | #ifndef LIMIT_QUOTE_H 2 | #define LIMIT_QUOTE_H 3 | 4 | #include "quote.h" 5 | 6 | class Limit_quote : public Quote 7 | { 8 | public: 9 | Limit_quote(); 10 | Limit_quote(const std::string& b, double p, std::size_t max, double disc): 11 | Quote(b,p), max_qty(max), discount(disc) { } 12 | 13 | double net_price(std::size_t n) const override 14 | { return n * price - discount * price * ( max_qty > n ? n : max_qty ); } 15 | 16 | private: 17 | std::size_t max_qty = 0; 18 | double discount = 0.0; 19 | }; 20 | 21 | #endif // LIMIT_QUOTE_H 22 | -------------------------------------------------------------------------------- /ch15/ex15.7/quote.cpp: -------------------------------------------------------------------------------- 1 | #include "quote.h" 2 | 3 | -------------------------------------------------------------------------------- /ch15/ex15.7/quote.h: -------------------------------------------------------------------------------- 1 | #ifndef QUOTE_H 2 | #define QUOTE_H 3 | 4 | #include 5 | 6 | class Quote 7 | { 8 | public: 9 | Quote() = default; 10 | Quote(const std::string &b, double p) : 11 | bookNo(b), price(p) { } 12 | 13 | std::string isbn() const { return bookNo; } 14 | virtual double net_price(std::size_t n) const { return n * price; } 15 | 16 | virtual ~Quote() = default; 17 | 18 | private: 19 | std::string bookNo; 20 | 21 | protected: 22 | double price = 0.0; 23 | 24 | }; 25 | 26 | #endif // QUOTE_H 27 | -------------------------------------------------------------------------------- /ch16/ex16.12.13/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 02 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.12: 10 | //! Write your own version of the Blob and BlobPtr templates. including the 11 | //! various const members that were not shown in the text. 12 | //! 13 | //! Exercise 16.13: 14 | //! Explain which kind of friendship you chose for the equality and relational 15 | //! operators for BlobPtr. 16 | // As shown in the class body. 17 | //! 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "Blob.h" 25 | #include "blobptr.h" 26 | 27 | int main() 28 | { 29 | 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ch16/ex16.16/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 02 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.16: 10 | //! Rewrite the StrVec class (§ 13.5, p. 526) as a template named Vec. 11 | //! 12 | 13 | #include "vec.h" 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | Vec v = {1,2,3,4,5}; 20 | 21 | Vec v2; 22 | 23 | v2 = v; 24 | std::cout << v2.capacity() << "\n"; 25 | v2.push_back(99); 26 | v2.resize(2,2); 27 | 28 | for (auto t : v2) 29 | std::cout << t << " "; 30 | 31 | 32 | std::cout << v2.capacity() << "\n"; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /ch16/ex16.21.22/DebugDelete.h: -------------------------------------------------------------------------------- 1 | #ifndef DEBUGDELETE_H 2 | #define DEBUGDELETE_H 3 | 4 | #include 5 | 6 | class DebugDelete 7 | { 8 | public: 9 | DebugDelete(std::ostream& s = std::cerr) : os(s) { } 10 | template 11 | void operator() (T* p) const 12 | { 13 | os << "deleting unique_ptr" << std::endl; 14 | delete p; 15 | } 16 | 17 | private: 18 | std::ostream& os; 19 | }; 20 | #endif // DEBUGDELETE_H 21 | -------------------------------------------------------------------------------- /ch16/ex16.21.22/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 03 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.21: 10 | //! Write your own version of DebugDelete. 11 | //! 12 | //! Exercise 16.22: 13 | //! Revise your TextQuery programs from § 12.3 (p. 484) so that the shared_ptr 14 | //! members use a DebugDelete as their deleter (§ 12.1.4, p. 468). 15 | //! 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "DebugDelete.h" 22 | #include 23 | 24 | #include "wy_queryresult.h" 25 | #include "wy_textquery.h" 26 | 27 | int main() 28 | { 29 | 30 | 31 | 32 | 33 | return 0; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /ch16/ex16.24/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 03 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.24: 10 | //! Add a constructor that takes two iterators to your Blob template. 11 | //! 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #include 19 | #include 20 | 21 | 22 | int main() 23 | { 24 | std::vector v = {1,2,3,4,5}; 25 | Blob b(v.begin(), v.end()); 26 | return 0; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /ch16/ex16.28/DebugDelete.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file DebugDelete.h 3 | * @author Alan.W 4 | * @date 04 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | 9 | #ifndef DEBUGDELETE_H 10 | #define DEBUGDELETE_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief The DebugDelete class is a deleter functor using delete 16 | */ 17 | class DebugDelete 18 | { 19 | public: 20 | DebugDelete(std::ostream& s = std::cerr) : os(s) { } 21 | template 22 | void operator() (T* p) const 23 | { 24 | os << "deleting ptr" << std::endl; 25 | delete p; 26 | } 27 | 28 | private: 29 | std::ostream& os; 30 | }; 31 | #endif // DEBUGDELETE_H 32 | -------------------------------------------------------------------------------- /ch16/ex16.28/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 04 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.28 Write your own versions of shared_ptr and unique_ptr 10 | //! 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "DebugDelete.h" 18 | #include "shared_pointer.h" 19 | #include "unique_pointer.h" 20 | 21 | 22 | 23 | 24 | int main() 25 | { 26 | std::vector> v; 27 | 28 | for(int u = 0; u !=10 ; ++u) 29 | v.push_back(unique_pointer(new int(u))); 30 | 31 | for(auto& sp : v) 32 | std::cout << *sp << "\n"; 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /ch16/ex16.29/DebugDelete.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file DebugDelete.h 3 | * @author Alan.W 4 | * @date 04 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | 9 | #ifndef DEBUGDELETE_H 10 | #define DEBUGDELETE_H 11 | 12 | #include 13 | 14 | /** 15 | * @brief The DebugDelete class is a deleter functor using delete 16 | */ 17 | class DebugDelete 18 | { 19 | public: 20 | DebugDelete(std::ostream& s = std::cerr) : os(s) { } 21 | template 22 | void operator() (T* p) const 23 | { 24 | os << "deleting ptr" << std::endl; 25 | delete p; 26 | } 27 | 28 | private: 29 | std::ostream& os; 30 | }; 31 | #endif // DEBUGDELETE_H 32 | -------------------------------------------------------------------------------- /ch16/ex16.29/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 04 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.29: 10 | //! Revise your Blob class to use your version of shared_ptr rather than the 11 | //! library version. 12 | //! 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "DebugDelete.h" 20 | #include "shared_pointer.h" 21 | #include "unique_pointer.h" 22 | #include "Blob.h" 23 | 24 | int main() 25 | { 26 | Blob b; 27 | b.push_back("sss"); 28 | 29 | 30 | b[0] = "zzzz"; 31 | std::cout << b[0] << "\n"; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /ch16/ex16.41/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 07 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.41: 10 | //! Write a version of sum with a return type that is guaranteed to be large 11 | //! enough to hold the result of the addition. 12 | //! 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | template 20 | auto sum(T lhs, T rhs) -> decltype( lhs + rhs) 21 | { 22 | return lhs + rhs; 23 | } 24 | 25 | int main() 26 | { 27 | auto s= sum(123456789123456789123456789123456789123456789, 123456789123456789123456789123456789123456789) ; 28 | ; 29 | ; 30 | } 31 | -------------------------------------------------------------------------------- /ch16/ex16.51.52/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 12 Feb 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 16.51: 10 | //! Determine what sizeof...(Args) and sizeof...(rest) return for each call to foo in this section. 11 | //! 12 | //! Exercise 16.52: 13 | //! Write a program to check your answer to the previous question. 14 | //! 15 | 16 | #include 17 | 18 | template 19 | void foo(T t,Args ...args) 20 | { 21 | std::cout << sizeof...(Args) << std::endl; 22 | std::cout << sizeof...(args) << std::endl; 23 | } 24 | 25 | 26 | int main() 27 | { 28 | foo(1,2); 29 | foo(1,23,4,5,6); 30 | } 31 | -------------------------------------------------------------------------------- /ch17/ex17.1.2/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 3 Mar 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 17.1: 10 | //! Define a tuple that holds three int values and initialize the members to 10, 20, and 30. 11 | //! 12 | //! Exercise 17.2: 13 | //! Define a tuple that holds a string, a vector, and a pair. 14 | //! 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | int main() 23 | { 24 | std::tuple i3 {10,20,30}; 25 | std::tuple, std::pair> t; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ch17/ex17.21/data/record.txt: -------------------------------------------------------------------------------- 1 | green (9998886666 9996668888 2 | morgan 2015552368 8625550123 3 | drew 9735550130 4 | lee 6095550132 2015550175 8005550000 5 | -------------------------------------------------------------------------------- /ch17/ex17.3/main.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * @file main.cpp 3 | * @author Alan.W 4 | * @date 3 Mar 2014 5 | * @remark This code is for the exercises from C++ Primer 5th Edition 6 | * @note 7 | ***************************************************************************/ 8 | //! 9 | //! Exercise 17.3: 10 | //! Rewrite the TextQuery programs from § 12.3 (p. 484) to use a tuple instead 11 | //! of the QueryResult class. Explain which design you think is better and why. 12 | //! 13 | // The orignal way is more formal.The second way is quick to implement ,but hard to 14 | // refactor.So the second way is better for testing. 15 | //! 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | int main() 24 | { 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ch18/README.md: -------------------------------------------------------------------------------- 1 | ##Exercise 18.1 2 | 3 | > What is the type of the exception object in the following throws? 4 | > 5 | > **(a)**`range_error r("error");` 6 | > `throw r`; 7 | > **(b)**`exception *p = &r;` 8 | > `throw *P;` 9 | 10 | >What would happen if the `throw` in **(b)** were written as `throw p`? 11 | 12 | The type of the exception object in (a) is range_error which is used to report range errors in internal computations. 13 | The type of the exception object in (b) is exception. 14 | If the "throw" in (b) were written as "throw p", there will be a runtime error. 15 | 16 | 17 | ##Exercise 18.2 18 | 19 | > Explain what happens if an exception occurs at the indicated point: 20 | 21 | 22 | ```cpp 23 | void exercise(int *b, int *e) 24 | { 25 | vector v(b,e); 26 | int *p = new int[v.size()]; 27 | ifstream in("ints"); 28 | // exception occurs here 29 | } 30 | ``` 31 | 32 | The space "p" points will not be free. There will be a memory leak. 33 | 34 | ##Exercise 18.3 35 | 36 | -------------------------------------------------------------------------------- /data/book.txt: -------------------------------------------------------------------------------- 1 | 0-201-78345-X 3 20 2 | 0-201-78345-X 2 25 3 | 0-201-78346-X 1 100 4 | 0-201-78346-X 2 99.9 5 | 0-201-78346-X 6 89.9 6 | -------------------------------------------------------------------------------- /data/even.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 4 3 | 6 4 | 8 5 | -------------------------------------------------------------------------------- /data/given_to_transform.txt: -------------------------------------------------------------------------------- 1 | where r u 2 | y dont u send me a pic 3 | k thk l8r -------------------------------------------------------------------------------- /data/input.txt: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 2 | -------------------------------------------------------------------------------- /data/letter.txt: -------------------------------------------------------------------------------- 1 | In typography, an ascender is the portion of a minuscule letter in a Latin-derived alphabet that extends above the mean line of a font. That is, the part of a lower-case letter that is taller than the font's x-height. 2 | 3 | Ascenders, together with descenders, increase the recognizability of words. For this reason, British road signs no longer use all capital letters.[1] 4 | 5 | Studies made at the start of the construction of the British motorway network concluded that words with mixed-case letters were much easier to read than "all-caps" and a special font was designed for motorway signs. These then became universal across the U.K. See Road signs in the United Kingdom. -------------------------------------------------------------------------------- /data/odd.txt: -------------------------------------------------------------------------------- 1 | 1 3 5 7 9 -------------------------------------------------------------------------------- /data/phonenumbers.txt: -------------------------------------------------------------------------------- 1 | morgan 2015552368 8625550123 2 | drew 9735550130 3 | lee 6095550132 2015550175 8005550000 -------------------------------------------------------------------------------- /data/storyDataFile.txt: -------------------------------------------------------------------------------- 1 | Alice Emma has long flowing red hair. 2 | Her Daddy says when the wind blows 3 | through her hair, it looks almost alive, 4 | like a fiery bird in flight. 5 | A beautiful fiery bird, he tells her, 6 | magical but untamed. 7 | "Daddy, shush, there is no such thing," 8 | she tells him, at the same time wanting 9 | him to tell her more. 10 | Shyly, she asks, "I mean, Daddy, is there?" 11 | -------------------------------------------------------------------------------- /data/word_transformation.txt: -------------------------------------------------------------------------------- 1 | brb be right back 2 | k okay? 3 | y why 4 | r are 5 | u you 6 | pic picture 7 | thk thanks! 8 | l8r later -------------------------------------------------------------------------------- /data/word_transformation_bad.txt: -------------------------------------------------------------------------------- 1 | l8r -------------------------------------------------------------------------------- /generate_format_command.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | from os import listdir 3 | from os.path import isfile, join 4 | 5 | if len(argv) > 1: 6 | mypath = argv[1] 7 | else: 8 | mypath = '.' 9 | 10 | print 'clang-format -i', 11 | 12 | onlyfiles = [ f for f in listdir(mypath) if isfile(join(mypath, f)) ] 13 | for file in onlyfiles: 14 | if (file.endswith(('.cpp', '.cc', '.h'))): 15 | print mypath + '\\' + file, 16 | --------------------------------------------------------------------------------