130 likes | 363 Views
Code Update. 01/ 16/ 2013. Agenda. OOP API Update (Semi-)Automated Composition. OOP API Update. Working through examples in e-book Presently implemented a Set and Bag Working towards a generic Class implementation Fairly complicated pointer indirection. OOP API Update.
E N D
Code Update 01/16/2013
Agenda • OOP API Update • (Semi-)Automated Composition
OOP API Update • Working through examples in e-book • Presently implemented a Set and Bag • Working towards a generic Class implementation • Fairly complicated pointer indirection
OOP API Update • (show code example)
(Semi-)Automated Composition • Start with Quicksort program • Identify methods for composing in merge/bubble sorts • All methods here have already been implemented, now identifying methods for automating them • All non-OOP at this point
void run_sort(struct Sorter* s); int main(intargc, char* argv[]) { struct Sorter s; inti; // create and output original numbers int numbers[SIZE] = {10, 8, 5, 9, 1, 3, 7, 2, 4, 6}; // initialize generic data producer setup_data(&s, (int*)numbers); // print initial print(&s); // call our sorting function run_sort(&s); // print print(&s); return 0; } void run_sort(struct Sorter* _s) { // calling quicksort int* (*qs)(int*, int, int) = &quicksort; _s->sort_fn = qs; call_sort(_s); } $ [10 8 5 9 1 3 7 2 4 6 ] [1 2 3 4 5 6 7 8 9 10 ]
void run_sort(struct Sorter* s); int main(intargc, char* argv[]) { struct Sorter s; inti; // create and output original numbers int numbers[SIZE] = {10, 8, 5, 9, 1, 3, 7, 2, 4, 6}; // initialize generic data producer setup_data(&s, (int*)numbers); // print initial print(&s); // call our sorting function run_sort(&s); // print print(&s); return 0; } void run_sort(struct Sorter* _s) { // calling quicksort int* (*qs)(int*, int, int) = &quicksort; _s->sort_fn = qs; call_sort(_s); } Data producer / consumer Kick off quicksort Calling quicksort via function pointer (existing) Could easily be a pure call to quicksort(int*, int, int) $ [10 8 5 9 1 3 7 2 4 6 ] [1 2 3 4 5 6 7 8 9 10 ]
Prototypes Struct int* quicksort(int* input, int p, int r); intbubble_sort(int* input); void merge_sort(int* input, int p, int r); structSorter { int numbers_[SIZE]; int* (*sort_fn)(int*, int, int); } • Swap in bubble sort • From prototype, we know that bubble_sort takes in an int* and returns void • We can assume sorting is done either: • In-place (returned via parameter pointer) • Internally (updates local/global data) • Recognizing this method will require extra information in method signature
Prototypes Struct int* quicksort(int* input, int p, int r); intbubble_sort(int* input); void merge_sort(int* input, int p, int r); structSorter { int numbers_[SIZE]; int* (*sort_fn)(int*, int, int); } • Assume sorting done in-place • Our data producer / consumer are the same (struct Sorter s) • Composition options: • [Data] • [1] – Simply pass pointer to our array (s.numbers) • [2] – Copy our array to a temporary variable, pass it in, and copy back after bubble_sortretursn • This has more overhead, but may be necessary if we want to preserve our original data structure
Prototypes Struct int* quicksort(int* input, int p, int r); intbubble_sort(int* input); void merge_sort(int* input, int p, int r); structSorter { int numbers_[SIZE]; int* (*sort_fn)(int*, int, int); } • Composition options: • [Call] • [1] – Hijack run_sortmethod for use as our own wrapper (injection) • [2] – Comment out run_sortand inject our own code • From either [1] or [2], we can: • [1] – Call method in place (code injection) • [2] – Create a wrapper to directly call bubble_sort • [3] – Create a wrapper to use existing function pointer • [4] – Add a new function prototype to Sorter to match bubble_sort
Prototypes Struct int* quicksort(int* input, int p, int r); intbubble_sort(int* input); void merge_sort(int* input, int p, int r); structSorter { int numbers_[SIZE]; int* (*sort_fn)(int*, int, int); } • Composition options: • [Call] • Parameter consideration • bubble_sorttakes a single int* parameter, where quick_sort takes an int* and 2 ints • Same issue will occur in merge_sort • We will need context from a method signature to decide what values should be used • Automate this with continuance or def-use chain analyses?
Prototypes Struct int* quicksort(int* input, int p, int r); intbubble_sort(int* input); void merge_sort(int* input, int p, int r); structSorter { int numbers_[SIZE]; int* (*sort_fn)(int*, int, int); } • Now we want to compose in merge_sort • We determine from the prototype that it takes 3 parameters • Need context to understand what they all mean • For instance, if not an int* for the first parameter, but we know it will be the data to be sorted, we’d need to transform our data producer into what is necessary • The [Call] portion of composition, to me, would be essentially the same
Next Steps • Continue OOP framework until I can provide a Sorting Class • Define method signatures (pre/post conditions)